1、C#实现的异步套接字封装了server与clientC#实现的异步套接字,封装了server与client最近半年以来都在从事suse10下的C+开发,开发工具也从豪门visual studio10降到了代码查看工具source insight。不过不得不说source insight阅读代码的效率绝对超过visual studio,虽然visual studio也能设置哪些功能,但真心没source insight顺手。不过悲剧的就是写代码的支持比文本好不了多少,调试的话,只能上传到suse10服务器上去然后慢慢的gdb调试了,最头大的就是那个makefile的编写,实在让人累。还是怀念wi
2、ndows下那种豪华的日子。废话不多说了,我写这篇文章不是为了诉苦的,只是为了继续写网络这边的。以前写过windows下的C+的网络编程的一些日子,虽然也被喷过不少,不过今天我还是要来写网络编程,只是语言更换为豪华的C#。之所以说C#豪华,相信同时使用C#与C+的人能体会到。frame work实在是太强大了,基本我就关注一点点东西就行了,很多类似工具的东西都是可以直接拿过来使用,而且最为关键的是我们在天朝,不用花钱用企业版,小小鄙视下自己,不过我还是会继续支持山寨盗版,谁让我是屌丝呢。今天文章中写的是异步,纯粹的异步,当然很多人看来很简单了,而且里面很多东西值得商榷,不过说真的,我真心感谢C
3、#的线程池,不然我还要自己去写个threadpool。而且我没办法保证我写的没问题。直接上代码了,不讲思路了,没时间,最近太忙,已经几天没睡好了。using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Net.Sockets;using System.Net;using System.Threading;namespace PPT.Comm/ / 接收数据流/ / 异步套接字/ 接收到的数据流public delegate void AsyncDataAccep
4、tedEventHandler(AsyncSocket m_pSocket, byte m_pDatagram);/ / 发送完毕/ / 异步套接字/ 发送结果public delegate void AsyncDataSendedEventHandler(AsyncSocket m_pSocket, bool m_pIsSuccess);/ / 接收连接委托/ / 异步套接字public delegate void AsyncSocketAcceptEventHandler(AsyncSocket m_pSocket);/ / 关闭连接委托/ / 异步套接字public delegate v
5、oid AsyncSocketClosedEventHandler(AsyncSocket m_pSocket);/ / State object for receiving data from remote device./ class StateObject/ Client socket.public Socket workSocket = null;/ Size of receive buffer.public const int BufferSize = 1024 * 256;/ Receive buffer.public byte buffer = new byteBufferSiz
6、e;/ Received data string.public StringBuilder sb = new StringBuilder();/ / 异步SOCKET/ public class AsyncSocket#region 私有字段 成员private Socket m_socket = null; /socketstring m_id = ; /socket唯一标识,GUIDprivate readonly bool m_isSerevr; /服务器标志位private int m_iBackBag;private string m_ipAddress;private int m_
7、port;private AsyncDataAcceptedEventHandler m_onAsyncDataAcceptedEvent = null; /接收数据流private AsyncDataSendedEventHandler m_onAsyncDataSendedEvent = null; /发送结束private AsyncSocketAcceptEventHandler m_onAsyncSocketAcceptEvent = null; /接收连接private AsyncSocketClosedEventHandler m_onAsyncSocketClosedEvent
8、 = null; /关闭连接#endregion#region 公共属性 成员/ / 获取SOCKET标志位/ public string ID get return m_id; / / 设置或获取机器标志位/ public string MachineKey set; get; / / 获取、设置连接对象/ public Socket LinkObjectgetreturn m_socket;setm_socket = value;/ / 设置或获取线程退出标识/ public bool IsExit set; get; #endregion#region 公共事件 成员/ / 连接关闭事件
9、/ public event AsyncSocketClosedEventHandler AsyncSocketClosedEventaddm_onAsyncSocketClosedEvent += value;removem_onAsyncSocketClosedEvent -= value;/ / 连接接收事件/ public event AsyncSocketAcceptEventHandler AsyncSocketAcceptEventaddm_onAsyncSocketAcceptEvent += value;removem_onAsyncSocketAcceptEvent -=
10、value;/ / 数据接收完成事件/ public event AsyncDataAcceptedEventHandler AsyncDataAcceptedEventaddthis.m_onAsyncDataAcceptedEvent += value;removethis.m_onAsyncDataAcceptedEvent -= value;/ / 数据发送完成事件/ public event AsyncDataSendedEventHandler AsyncDataSendedEventaddm_onAsyncDataSendedEvent += value;removem_onAs
11、yncDataSendedEvent -= value;#endregion#region 构造函数 成员/ / 构造函数/ / 主机地址,可为机器名或者IP/ 主机端口/ 是否作为服务器,默认为false/ 支持多少个客户端public AsyncSocket(string m_pHostAddrss, int m_pHostPort, bool m_pIsAsServer = false, int m_pIBackBag = 10)m_isSerevr = m_pIsAsServer;m_iBackBag = m_pIBackBag;m_ipAddress = m_pHostAddrss;
12、m_port = m_pHostPort;m_id = Guid.NewGuid().ToString();/ / 构造函数,用于服务器构造与客户端的异步socket/ / 客户端socketprivate AsyncSocket(Socket linkObject)m_socket = linkObject;m_id = Guid.NewGuid().ToString();#endregion#region 公共方法/ / 打开通道/ public void AsyncOpen()if (m_isSerevr)IPAddress ip = Dns.GetHostAddresses(m_ipA
13、ddress)0;IPEndPoint ipe = new IPEndPoint(ip, m_port);m_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);m_socket.Bind(ipe);m_socket.Listen(m_iBackBag);m_socket.BeginAccept(new AsyncCallback(AcceptCallBack), null);/异步elseIPAddress ip = Dns.GetHostAddresses(m_ipAddr
14、ess)0;IPEndPoint ipe = new IPEndPoint(ip, m_port);m_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);m_socket.Connect(ipe);/ / 发送二进制数据/ / public void AsyncSend(byte SendData)m_socket.BeginSend(SendData, 0, SendData.Length, 0, new AsyncCallback(SendCallBack), m_soc
15、ket);/ / 关闭通道/ public void AsyncClose()if (!m_isSerevr)m_socket.Shutdown(SocketShutdown.Both);/关闭接收发送流m_socket.BeginDisconnect(false, CloseCallBack, m_socket);/开始尝试断开else m_socket.Shutdown(SocketShutdown.Both);/关闭接收发送流Thread.Sleep(200);/等待现有任务处理完成m_socket.Dispose();/释放所有本地资源/ / 开始接受数据,连接建立之后,调用此方法/
16、public void BeginAcceptData()/开始接收数据StateObject state = new StateObject();state.workSocket = m_socket;m_socket.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);#endregion#region 私有方法 成员#endregion#region 回调函数 成员/ / 接受客户端连接处理/ / private void AcceptCal
17、lBack(IAsyncResult ar)Socket handler = m_socket.EndAccept(ar);AsyncSocket NewSocket = new AsyncSocket(handler);/激发事件,异步触发if (m_onAsyncSocketAcceptEvent != null)foreach (AsyncSocketAcceptEventHandler item in m_onAsyncSocketAcceptEvent.GetInvocationList()item.BeginInvoke(NewSocket, null, null);/继续投递监听
18、请求m_socket.BeginAccept(new AsyncCallback(AcceptCallBack), null);/ / 接受字节流处理/ / private void ReceiveCallback(IAsyncResult ar)tryStateObject state = ar.AsyncState as StateObject;/读取数据int bytesRead = m_socket.EndReceive(ar);if (bytesRead 0)byte _Readbyte = new bytebytesRead;Array.Copy(state.buffer, 0,
19、_Readbyte, 0, bytesRead);/接收完成,激发事件if (m_onAsyncDataAcceptedEvent != null)foreach (AsyncDataAcceptedEventHandler item in m_onAsyncDataAcceptedEvent.GetInvocationList()item.BeginInvoke(this, _Readbyte, null, null);state = new StateObject();/继续投递接收委托state.workSocket = m_socket;m_socket.BeginReceive(st
20、ate.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);catch (SocketException)if (m_onAsyncSocketClosedEvent != null)foreach (AsyncSocketClosedEventHandler item in m_onAsyncSocketClosedEvent.GetInvocationList()item.BeginInvoke(this, null, null);/ / 发送结束处理/ / private voi
21、d SendCallBack(IAsyncResult ar)trym_socket.EndSend(ar);if (m_onAsyncDataSendedEvent != null)foreach (AsyncDataSendedEventHandler item in m_onAsyncDataSendedEvent.GetInvocationList()item.BeginInvoke(this, true, null, null);catch (SocketException)if (m_onAsyncDataSendedEvent != null)foreach (AsyncData
22、SendedEventHandler item in m_onAsyncDataSendedEvent.GetInvocationList()item.BeginInvoke(this, false, null, null);if (m_onAsyncSocketClosedEvent != null)foreach (AsyncSocketClosedEventHandler item in m_onAsyncSocketClosedEvent.GetInvocationList()item.BeginInvoke(this, null, null);/ / 关闭后处理/ / private
23、 void CloseCallBack(IAsyncResult ar)trym_socket.EndDisconnect(ar);m_socket.Dispose();if (m_onAsyncDataSendedEvent != null)foreach (AsyncSocketClosedEventHandler item in m_onAsyncSocketClosedEvent.GetInvocationList()item.BeginInvoke(this, null, null);catch (SocketException)if (m_onAsyncSocketClosedEv
24、ent != null)foreach (AsyncSocketClosedEventHandler item in m_onAsyncSocketClosedEvent.GetInvocationList()item.BeginInvoke(this, null, null); #endregion代码注释还是蛮详细的,相信你看了也没什么不懂的地方。唯一让我不爽的是我异步事件不得不foreach (AsyncSocketAcceptEventHandler item in m_onAsyncSocketAcceptEvent.GetInvocationList()item.BeginInvoke(NewSocket, null, null); 这样的写法,很蛋疼。也试验了Action asyncAction = () = m_onAsyncSocketAcceptEvent ();asyncAction.BeginInvoke( null , null); 但郁闷的发现其实action虽然异步了,但那些事件还是顺序触发的,根本不是并发触发。无奈还是写那个蛋疼的foreach语句。顺便提到一句那个foreach中类型写全了,别用var,因为var会自动推断为Delegate。当然你自己再转换下也行,如果你喜欢的话。
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1