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调用它时结束函数

 

.Net asynchronous Socket methods

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()
IAsyncResult BeginReceiveFrom(byte[] buffer, int offset, int size, SocketFlags sockflag, ref EndPoint ep, AsyncCallback callback, object state)
这里特别要注意ep这个参数是ref的---未完明天继续,下篇是实例

 

 

posted @ 2010-12-19 00:06  张土土  阅读(686)  评论(0编辑  收藏  举报