Using Asynchronous Sockets---异步Socket的使用
The Socket object contains methods that utilize the AsyncCallback class to call completion methods when the network functions are finished. This allows the application to continue processing other events while waiting for network operations to complete their work.
Socket对象中有一些函数(方法),这些函数会使用AsyncClallBack类去调用 执行网络功能的函数(自己定义的函数)完成后
这样的方式可以使程序在执行网络操作的时候同时执行其他操作,而不会出现执行网络通信 未得到回应之前程序一直处于等待状态的情况。
微软把Scoket中的异步方法 把常用的网络函数 分成两大块
1. Begin开头的且 注册了AsyncCallback方法
2. End开头的用于当AsyncCallback调用它时结束函数
Requests Started By… |
Description of Request |
Requests Ended BY… |
---|---|---|
BeginAccept() |
To accept an incoming connection |
EndAccept() |
BeginConnect() |
To connect to a remote host |
EndConnect() |
BeginReceive() |
To retrieve data from a socket |
EndReceive() |
BeginReceiveFrom() |
To retrieve data from a specific remote host |
EndReceiveFrom() |
BeginSend() |
To send data from a socket |
EndSend() |
BeginSendTo() |
To send data to a specific remote host |
EndSendTo() |
Note |
Notice that these methods apply only to Socket objects. In .NET Framework release 1, the TcpClient, TcpListener, and UdpClient classes do not include asynchronous methods. |
建立连接
BeginAccept和EndAccept方法
BeginAccept用于接收从客户端传入的连接,原型:
IAsyncResult BeginAccept(AsyncCallback callback,object state)
callback是回调函数,state会成为回调函数的参数的一个属性,这在下文会说到,看例子:
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint iep = new IPEndPoint(IPAddress.Any, 9050);
sock.Bind(iep);
sock.Listen(5);
sock.BeginAccept(new AsyncCallback(CallAccept), sock);
这样在每次有连接传入的时候,就会调用CallAccept方法,在CallAccept方法中必须包含EndAccept方法,用来结束接收
EndAccept原型:Socket EndAccept(IAsyncResult iar);iar有个AsyncState属性,存储着BeginAccpet中的object参数CallAccept函数一般是这样子private static void CallAccept(IAsyncResult iar){Socket server = (Socket)iar.AsyncState;Socket client = server.EndAccept(iar);. . .}Socket server = (Socket)iar.AsyncState;在之前的代码中传递了一个socket对象,所以这个时候可以通过类型转换得到Socket client = server.EndAccept(iar);这样可以得到一个对客户端的socket对象BeginConnect方法和EndConnect方法这是客户端的方法IAsyncResult BeginConnect(EndPoint ep, AsyncCallback callback, Object state)因为是客户端的方法所以自然要指定服务器端了,ep就是服务器端,剩下的两个参数就类似于上文的服务器端接收方法了惯例,看个例子Socket newsock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);IPEndPoint iep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9050);newsock.BeginConnect(iep, new AsyncCallback(Connected), newsock);public static void Connected(IAsyncResult iar){ Socket sock = (Socket)iar.AsyncState;try { sock.EndConnect(iar); }catch (SocketException){ Console.WriteLine("Unable to connect to host"); }}因为服务器端可能不存在所以要把连接动作放在try中 这是一个好习惯发送和接收数据BeginSend()和EndSend()原型:IAsyncResult BeginSend(byte[] buffer, int offset, int size, SocketFlags sockflag, AsyncCallback callback, object state)例子:sock.BeginSend(data, 0, data.Length, SocketFlags.None, new AsyncCallback(SendData), sock);SendData 方法的格式int EndSend(IAsyncResult iar)例子:这两个方法是用于无连接的时候private static void SendData(IAsyncResult iar){Socket server = (Socket)iar.AsyncState;int sent = server.EndSend(iar);}BeginSendTo() 和 EndSendTo()IAsyncResult BeginSendTo(byte[] buffer, int offset, int size, SocketFlags sockflag, EndPoint ep, AsyncCallback callback, object state)所以要指定服务器端了IPEndPoint iep = new IPEndPoint(IPAddress.Parse("192.168.1.6"), 9050);
sock.BeginSendTo(data, 0, data.Length, SocketFlags.None, iep,new AsynCallback(SendDataTo), sock);EndSendTo的原型:int EndSendTo(IAsyncResult iar)//返回值是发送出去的位数BeginReceive() 和 EndReceive()IAsyncResult BeginReceive(byte[] buffer, int offset, int size, SocketFlags sockflag, AsyncCallback callback, object state)sock.BeginReceive(data, 0, data.Length, SocketFlags.None, new AsyncCallback(ReceivedData), sock);void ReceivedData(IAsyncResult iar){Socket remote = (Socket)iar.AsyncState;int recv = remote.EndReceive(iar);string receivedData = Encoding.ASCII.GetString(data, 0, recv);Console.WriteLine(stringData);}BeginReceiveFrom() 和 EndReceiveFrom()这里特别要注意ep这个参数是ref的---未完明天继续,下篇是实例IAsyncResult BeginReceiveFrom(byte[] buffer, int offset, int size, SocketFlags sockflag, ref EndPoint ep, AsyncCallback callback, object state)