Tcp 异步通信基础

Tcp 异步通信基础

前一篇实现了同步Tcp通信。同步通信在连接、发送、接收等都会阻塞线程,会造成界面假死。

只能满足部分需求,该篇介绍异步通信,你会爱上它的。

 

服务端代码:

class Program
{
  private static Socket socket;

  static void Main(string[] args)
  {
    socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    var hostAddresss = Dns.GetHostAddresses(Dns.GetHostName());
    var localAddress = hostAddresss.First(p => p.AddressFamily == AddressFamily.InterNetwork);
    var ipEndPoint = new IPEndPoint(localAddress, 4572);
    socket.Bind(ipEndPoint);
    socket.Listen(10);
    Console.WriteLine("服务器监听:" + ipEndPoint.ToString() + " 成功...");
    Console.WriteLine("开始异步监听客户进入...");

    //把服务端Socket 传入,方便后续的处理     socket.BeginAccept(
new AsyncCallback(OnClientEnterListener), socket);     Console.ReadLine();   }   static void OnClientEnterListener(IAsyncResult ar)   {
    //这里的Socket 是传入的服务器端Socket
    var serverSocket = (Socket)ar.AsyncState;     var clientSocket = serverSocket.EndAccept(ar);     var endPoint = clientSocket.RemoteEndPoint;     Console.WriteLine("客户:" + endPoint.ToString() + " 进入...");     var str = "Hello World!";     var data = Encoding.UTF8.GetBytes(str);     clientSocket.BeginSend(data, 0, data.Length, SocketFlags.None, new AsyncCallback(OnSendListener), clientSocket);
    //处理完成客户进入以后继续调用,让其继续监听客户进入     serverSocket.BeginAccept(
new AsyncCallback(OnClientEnterListener), serverSocket);   }   static void OnSendListener(IAsyncResult ar)   {     var clientSocket = (Socket)ar.AsyncState;     clientSocket.EndSend(ar);     var endPoint = clientSocket.RemoteEndPoint;     Console.WriteLine("关闭客户:" + endPoint.ToString() + " 连接...");     clientSocket.Close();   } }

 异步的服务器绑定和同步的差不多,接收部分多了个委托  static void OnClientEnterListener(IAsyncResult ar) 方法在有客户连接进来的时候会被回调,

这里值得注意的地方是: serverSocket.BeginAccept(new AsyncCallback(OnClientEnterListener), serverSocket); 这里的代码 处理完客户进入以后继续调用,要不然服务器就不会继续监听下一个客户进入了。

 

客户端代码:

class Program
{
  private static Socket socket;
  private static byte[] buffer;

  static void Main(string[] args)
  {
    socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    var hostAddresss = Dns.GetHostAddresses(Dns.GetHostName());
    var localAddress = hostAddresss.First(p => p.AddressFamily == AddressFamily.InterNetwork);
    var ipEndPoint = new IPEndPoint(localAddress, 4572);
    Console.WriteLine("正在连接服务器:" + ipEndPoint.ToString());
    socket.BeginConnect(ipEndPoint, new AsyncCallback(OnConnectListener), socket);
    Console.ReadLine();
  }

  static void OnConnectListener(IAsyncResult ar)
  {
    var clientSocket = (Socket)ar.AsyncState;
    try
    {
      clientSocket.EndConnect(ar);
    }
    catch (Exception ex)
    {
      Console.WriteLine("连接服务器异常:");
      Console.WriteLine(ex.Message);
      return;
    }

    Console.WriteLine("连接服务器成功...");
    Console.WriteLine("正在监听消息进入...");
    buffer = new byte[1024];
    clientSocket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(OnReceiveDataListener), clientSocket);
  }

  static void OnReceiveDataListener(IAsyncResult ar)
  {
    var clientSocket = (Socket)ar.AsyncState;
    int number = clientSocket.EndReceive(ar);
    //如果接收到的数据为0,说明服务器已经断开了连接
    if (number == 0)     {       Console.WriteLine("服务器已断开连接...");       return;     }     var str = Encoding.UTF8.GetString(buffer, 0, number);     Console.WriteLine("接收到服务器消息:" + str);
    //处理完成接收数据以后继续调用,让其继续监听数据进入     clientSocket.BeginReceive(buffer,
0, buffer.Length, SocketFlags.None, new AsyncCallback(OnReceiveDataListener), clientSocket);   } }

 异步客户端和同步差不多。只是多了个委托,用于操作完成以后回调。

需要注意的地方是:

1.如果接收到的消息大小为0,说明服务器已经断开了客户的连接。

2.接收消息处理完成以后继续监听。

posted @ 2014-12-09 13:14  忤逆小旭  阅读(264)  评论(0)    收藏  举报