您的位置:首页 > 理论基础 > 计算机网络

.Net网络通讯编程[利用Socket实现字串、文件、序列化对象传输]--使用封装的网络服务4[聊天室]

2012-03-28 09:54 1136 查看
本案例使用前面封装的网络服务类编写简易聊天室,采用Tcp和异步套接字相关技术:

示范代码using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using TcpLabCommon;
using System.Net.Sockets;
using System.Net;
using System.Configuration;
using System.Threading;
using System.IO;

namespace TcpLabChat1
{
public partial class FrmChat : Form
{
delegate void UpdateViewHandler(NetPacket packet);
delegate void UpdateViewWithMsgHandler(string msg);

/// <summary>
/// 文件对话框
/// </summary>
OpenFileDialog fd = new OpenFileDialog();

/// <summary>
/// Tcp服务对象[提供发包和收包功能],接收消息和文件使用
/// </summary>
NetPacketService tcpPacketServiceSvr = null;

/// <summary>
/// Tcp服务对象[提供发包和收包功能],发送消息和文件使用
/// </summary>
NetPacketService tcpPacketServiceClient = null;

/// <summary>
/// 客户端Socket[发送消息和文件]
/// </summary>
Socket clientSocket = null;

/// <summary>
/// 本地服务器名
/// </summary>
public string ServerName
{
get
{
return ConfigurationManager.AppSettings["ServerName"];
}
}

/// <summary>
/// 本地监听端口
/// </summary>
public Int32 ServerPort
{
get
{
return Convert.ToInt32(ConfigurationManager.AppSettings["ServerPort"]);
}
}

/// <summary>
/// 对方服务器名
/// </summary>
public String RemoteServerName
{
get
{
return ConfigurationManager.AppSettings["RemoteServerName"];
}
}

/// <summary>
/// 对方服务器监听端口
/// </summary>
public Int32 RemoteServerPort
{
get
{
return Convert.ToInt32(ConfigurationManager.AppSettings["RemoteServerPort"]);
}
}

public FrmChat()
{
InitializeComponent();
}

private void FrmChat_Load(object sender, EventArgs e)
{
ReceiveMessage();
}

/// <summary>
/// 异步接收对方发来的消息
/// </summary>
private void ReceiveMessage()
{
Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
EndPoint endPoint = new IPEndPoint(IPAddress.Parse(ServerName), ServerPort);//创建一个终结点
serverSocket.Bind(endPoint);//绑定终结点
serverSocket.Listen(0);//开始监听

serverSocket.BeginAccept(new AsyncCallback(AsyncCallbackAccept),serverSocket);//接收一个请求

}

private void AsyncCallbackAccept(IAsyncResult result)
{
Socket serverSocket = (Socket)result.AsyncState;
Socket ctSocket = serverSocket.EndAccept(result);
NetworkStream netStream = new NetworkStream(ctSocket);
tcpPacketServiceSvr = new NetPacketTcpAsynService(netStream);
(tcpPacketServiceSvr as NetPacketTcpAsynService).OnReceivedPacket += new TcpAsynHandler1(FrmChat_OnReceivedPacket);

tcpPacketServiceSvr.ReceivePacket();

}

void FrmChat_OnReceivedPacket(NetPacket packet)
{
//在窗口界面所在的线程运行委托指向的方法,避免跨线程访问UI问题
Invoke(new UpdateViewHandler(UpdateView), packet);
}

/// <summary>
/// 更新界面
/// </summary>
/// <param name="packet"></param>
private void UpdateView(NetPacket packet)
{
String msglist = txtMsgList.Text;
switch (packet.PacketHead.PType)
{
case PacketType.STRING:
msglist += "\r\n对方说:"+packet.Data.ToString();
break;
case PacketType.BINARY:
NetFile f = tcpPacketServiceSvr.ParseFile((Byte[])packet.Data);
msglist += "\r\n接收了对方发送的文件:"+f.FileName;
FileStream fs = null;
try
{
string fname = Application.StartupPath+"\\"+f.FileName;
fs = new FileStream(fname, FileMode.Create);
fs.Write(f.Content, 0, f.Content.Length);
fs.Flush();
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
finally
{
fs.Close();
}
break;
case PacketType.COMPLEX:
break;
default:
break;
}

txtMsgList.Text = msglist;
}

private void UpdateView(string msg)
{
String msglist = txtMsgList.Text;
msglist += "\r\n"+msg;
txtMsgList.Text = msglist;
}

/// <summary>
/// 发送消息
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnSendMsg_Click(object sender, EventArgs e)
{
if (txtMsg.Text.Trim().Length == 0)
return;

if (clientSocket == null)
{
clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
clientSocket.Connect(IPAddress.Parse(RemoteServerName), RemoteServerPort);
NetworkStream netStream = new NetworkStream(clientSocket);
tcpPacketServiceClient = new NetPacketTcpAsynService(netStream);
}
//注册事件,当发送成功后执行的函数[注意该事件只注册一次]
//取消订阅事件
(tcpPacketServiceClient as NetPacketTcpAsynService).OnAfterSendPacket -= new TcpAsynHandler2(FrmChat_OnAfterSendPacket);
//再次订阅事件
(tcpPacketServiceClient as NetPacketTcpAsynService).OnAfterSendPacket += new TcpAsynHandler2(FrmChat_OnAfterSendPacket);
//发包
tcpPacketServiceClient.SendText(txtMsg.Text.Trim());
}

/// <summary>
/// 当发送成功后执行的函数
/// </summary>
/// <param name="msg"></param>
void FrmChat_OnAfterSendPacket(NetPacketHead packetHead)
{
switch (packetHead.PType)
{
case PacketType.STRING:
String msglist = txtMsgList.Text;
msglist += "\r\n我说:" + txtMsg.Text.Trim();
txtMsgList.Text = msglist;
break;
case PacketType.BINARY:
//在窗口界面所在的线程运行委托指向的方法,避免跨线程访问UI问题
Invoke(new UpdateViewWithMsgHandler(UpdateView), "我发送了文件:" + new FileInfo(fd.FileName).Name);
break;
case PacketType.COMPLEX:
break;
default:
break;
}

}

/// <summary>
/// 发送文件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnSendFile_Click(object sender, EventArgs e)
{

if (fd.ShowDialog() == System.Windows.Forms.DialogResult.Cancel)
{
return;
}

if (clientSocket == null)
{
clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
clientSocket.Connect(IPAddress.Parse(RemoteServerName), RemoteServerPort);
NetworkStream netStream = new NetworkStream(clientSocket);
tcpPacketServiceClient = new NetPacketTcpAsynService(netStream);
}

//注册事件,当发送成功后执行的函数[注意该事件只注册一次]
//取消订阅事件
(tcpPacketServiceClient as NetPacketTcpAsynService).OnAfterSendPacket -= new TcpAsynHandler2(FrmChat_OnAfterSendPacket);
//再次订阅事件
(tcpPacketServiceClient as NetPacketTcpAsynService).OnAfterSendPacket += new TcpAsynHandler2(FrmChat_OnAfterSendPacket);

tcpPacketServiceClient.SendFile(fd.FileName);

}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐