.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); } } }
相关文章推荐
- .Net网络通讯编程[利用Socket实现字串、文件、序列化对象传输]--使用封装的网络服务3[聊天室]
- .Net网络通讯编程[利用Socket实现字串、文件、序列化对象传输]--使用封装的网络服务3[聊天室][使用IE浏览本页]
- .Net网络通讯编程[利用Socket实现字串、文件、序列化对象传输]--使用封装的网络服务2
- .Net网络通讯编程[利用Socket实现字串、文件、序列化对象传输]--使用封装的网络服务1[使用IE浏览本页]
- .Net网络通讯编程[利用Socket实现字串、文件、序列化对象传输]--使用封装的网络服务1
- .Net网络通讯编程[利用Socket实现字串、文件、序列化对象传输]--使用封装的网络服务2[使用IE浏览本页]
- .Net网络通讯编程[利用Socket实现字串、文件、序列化对象传输]--使用封装的网络服务4[聊天室][使用IE浏览本页]
- .Net网络通讯编程[利用Socket实现字串、文件、序列化对象传输]--类设计1[使用IE浏览本页]
- .Net网络通讯编程[利用Socket实现字串、文件、序列化对象传输]--类设计2[使用IE浏览本页]
- .Net网络通讯编程[利用Socket实现字串、文件、序列化对象传输]--类设计2
- .Net网络通讯编程[利用Socket实现字串、文件、序列化对象传输]--类设计1
- Net网络通讯编程[利用Socket实现字串、文件、序列化对象传输]--前面6篇博文全部源代码下载地址
- Net网络通讯编程[利用Socket实现字串、文件、序列化对象传输]--前面6篇博文全部源代码下载地址
- C#中使用异步Socket编程实现TCP网络服务的C/S的通讯构架(二)
- 在C#中使用异步Socket编程实现TCP网络服务的C/S的通讯构架(一)
- 在C#中使用异步Socket编程实现TCP网络服务的C/S的通讯构架
- 【转】 在C#中使用异步Socket编程实现TCP网络服务的C/S的通讯构架2
- 在C#中使用异步Socket编程实现TCP网络服务的C/S的通讯构架(二)----使用方法
- 在C#中使用异步Socket编程实现TCP网络服务的C/S的通讯构架
- 在C#中使用异步Socket编程实现TCP网络服务的C/S的通讯构架(一)----基础类库部分(来源:http://blog.csdn.net/yangjundeng/archive/2005/03/17/321920.aspx)