网络异步实现客户端
------------------------------------------------------------------客户端------------------------------------------------------------------
之前学习的客户端当然可以实现基本的功能,只是会出现卡顿的现象,用户的体验并不是很好,我们现在用异步实现这样的功能
具体完整的代码:
using System.Collections; using System.Collections.Generic; using UnityEngine; using System.Net.Sockets; using UnityEngine.UI; using System; public class Echo : MonoBehaviour { //定义套接字 Socket socket; //定义UGUI public InputField inputField; public Text text; //接收缓冲区 byte[] readBuff = new byte[1024]; string recvStr = " "; // 点击连接按钮 public void Connection() { //Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //Connect //socket.Connect("127.0.0.1", 8888); //Connect socket.BeginConnect("127.0.0.1", 8888, ConnectCallback, socket); } //Connect回调 public void ConnectCallback(IAsyncResult ar) { try { Socket socket = (Socket)ar.AsyncState; socket.EndConnect(ar); Debug.Log("Socket Connect Succ"); socket.BeginReceive(readBuff, 0, 1024, 0, ReceiveCallback, socket); } catch (SocketException ex) { Debug.Log("Socket Connect fail" + ex.ToString()); } } //Receive回调 public void ReceiveCallback(IAsyncResult ar) { try { Socket socket = (Socket)ar.AsyncState; int count = socket.EndReceive(ar); recvStr = System.Text.Encoding.Default.GetString(readBuff, 0, count); socket.BeginReceive(readBuff, 0, 1024, 0, ReceiveCallback, socket); } catch (SocketException ex) { Debug.Log("Socket Receive fail" + ex.ToString()); } } // 点击发送按钮 public void Send() { //Send string sendStr = inputField.text; byte[] sendBytes = System.Text.Encoding.Default.GetBytes(sendStr); socket.BeginSend(sendBytes, 0, sendBytes.Length, 0, SendCallback, socket); } //Send回调 public void SendCallback(IAsyncResult ar) { try { Socket socket = (Socket)ar.AsyncState; int count = socket.EndSend(ar); Debug.Log("Socket Send succ" + count); } catch (SocketException ex) { Debug.Log("Socket Send fail" + ex.ToString()); } } public void Update() { text.text = recvStr; } }
异步包括了三部分的异步,连接异步,发送异步,接收异步,也都是通过委托方法实现的。
------------------------------------------------------服务器-------------------------------------------------------------
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Net; using System.Net.Sockets; namespace EchoServer { class ClientState { public Socket socket; public byte[] readBuff = new byte[1024]; } class Program { //监听Socket static Socket listenfd; //客户端Socket及状态信息 static Dictionary<Socket, ClientState> clients = new Dictionary<Socket, ClientState>(); public static void Main(string[] args) { Console.WriteLine("Hello World !"); //Socket Socket listenfd = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //Bind IPAddress ipAdr = IPAddress.Parse("127.0.0.1"); IPEndPoint ipEp = new IPEndPoint(ipAdr, 8888); listenfd.Bind(ipEp); //Listen listenfd.Listen(0); Console.WriteLine("[服务器] 启动成功"); //Accept listenfd.BeginAccept(AcceptCallback, listenfd); //等待 Console.ReadLine(); } //Accept回调 public static void AcceptCallback(IAsyncResult ar) { try { Console.WriteLine("[服务器] Accept"); Socket listenfd = (Socket)ar.AsyncState; Socket clientfd = listenfd.EndAccept(ar); //clients列表 ClientState state = new ClientState(); state.socket = clientfd; clients.Add(clientfd, state); //接收数据BeginReceive clientfd.BeginReceive(state.readBuff, 0, 1024, 0, ReceiveCallback, state); //继续Accept listenfd.BeginAccept(AcceptCallback, listenfd); } catch (SocketException ex) { Console.WriteLine("Socket Accept fail"+ex.ToString()); } } //Receive回调 public static void ReceiveCallback(IAsyncResult ar) { try { ClientState state = (ClientState)ar.AsyncState; Socket clientfd = state.socket; int count = clientfd.EndReceive(ar); //客户端关闭 if (count == 0) { clientfd.Close(); clients.Remove(clientfd); Console.WriteLine("Socket Close"); return; } string recvStr = System.Text.Encoding.Default.GetString(state.readBuff, 0, count); byte[] sendBytes = System.Text.Encoding.Default.GetBytes("echo" + recvStr); foreach (ClientState s in clients.Values) { s.socket.Send(sendBytes); } clientfd.BeginReceive(state.readBuff, 0, 1024, 0, ReceiveCallback, state); } catch (SocketException ex) { Console.WriteLine("Socket Receive fail"+ex.ToString()); } } } }