你的位置:首页 > ASP.net教程

[ASP.net教程]Socket异步通信学习二


接下来是服务器部分,采用异步模式,新建了一个AsynServer类,用于存放socket服务器代码,主要有4个方法:

有一个全局socket,下面四个方法中都用到。

Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

类框架如下:

1.构造方法public AsynServer(IPEndPoint endpoint,int listenMaxNum)

  用于初始化socket服务器,IPEndPoint参数是socket绑定的终结点,listenMaxNum参数是监听队列的挂起的最大长度,代码如下:

 public AsynServer(IPEndPoint endpoint,int listenMaxNum)    {            socket.Bind(endpoint);   //绑定终结点        socket.Listen(listenMaxNum);//将socket至于侦听状态,设置挂起队列最大值为listenMaxNum        Console.WriteLine("正在连接客户端....");        AsynAccept();     //开始异步监听    //   return socket;    }

2.异步监听方法public void AsynAccept()

public void AsynAccept()    {        socket.BeginAccept(asyncResult => {        socket = socket.EndAccept(asyncResult);     //异步监听成功,返回socket        Console.WriteLine("客户端{0}异步连接成功", socket.RemoteEndPoint.ToString());              AsynReceive();          AsynSend("Server:Hello,client!");      }, null);    }

View Code

需注意的是异步socket的BeginAccept()方法必须以EndAccept()方法结束,EndAccept(asyncResult)通过回调BeginAccept中的asyncResult状态信息返回socket,这个socket是与客户端建立连接后的socket,需要把它赋给全局socket(后面的方法中会调用)。

另外,AsynAccept并不会阻塞主线程,因为系统会为BeginAccept()方法自动开一个线程,并阻塞该线程直到收到客户端连接,回调lamda表达式中的接收代码。

采用lamda变得式写的回调函数,不熟悉的同学请恶补一下吧,用起来很方便的:-)

连接成功了会收到客户端发来的信息,(AsynReceive()也是异步的,不会阻碍主线程),并给客户端发送问候信息,(AsynReceive()和AsynSend()都是异步的,不会阻碍主线程)。

3.异步接收方法private  void AsynReceive()

 private void AsynReceive()    {      byte[] data = new byte[1024];//接收缓存      string receiveStr;      socket.BeginReceive(data, 0, data.Length, SocketFlags.None, asyncResult => {        int length = socket.EndReceive(asyncResult);        if (length != 0)        {          receiveStr = Encoding.ASCII.GetString(data, 0, length);//获取缓存中的信息          Console.WriteLine(receiveStr);                     AsynReceive();//继续开新线程接收        }        else {                      Console.WriteLine("客户端{0}:关闭socket连接", socket.RemoteEndPoint.ToString());//socket.RemoteEndPoint.ToString()是客户端IP地址          socket.Close();        }      }, null);                }

AsynReceive()

4.异步发送方法public void AsynSend()

 public void AsynSend(string msg)    {      byte[] data = Encoding.UTF8.GetBytes(msg);      socket.BeginSend(data, 0, data.Length, SocketFlags.None, asyncResult =>      {        int length = socket.EndSend(asyncResult);        Console.WriteLine("message send to {0} successfully", socket.RemoteEndPoint.ToString());      }, null);          }

public void AsynSend(string msg)

因为socket收发都是采用字节流的形式,所以接收需要用byte[] data = new byte[1024],缓存收到的字节流,然后通过Encoding.ASCII.GetString(data, 0, length)方法把字节流转化为字符串输出;发送通过byte[] data = Encoding.UTF8.GetBytes(msg),把字符串信息转化为字节流发送。EndReceive(),EndSend()方法返回的都是收发字节数(int)

以上都是最简单的,只能实现基本的通信功能,后期会在此基础上完善,帮助初学者少走弯路,我当时可是学的头昏眼花-_-||

下篇是采用与服务器完全不同模式的客户端,同步模式