接下來是伺服器部分,採用非同步模式,新建了一個AsynServer類,用於存放socket伺服器代碼,主要有4個方法: 有一個全局socket,下麵四個方法中都用到。 Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.S ...
接下來是伺服器部分,採用非同步模式,新建了一個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)
以上都是最簡單的,只能實現基本的通信功能,後期會在此基礎上完善,幫助初學者少走彎路,我當時可是學的頭昏眼花-_-||
下篇是採用與伺服器完全不同模式的客戶端,同步模式