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.接收消息处理完成以后继续监听。

浙公网安备 33010602011771号