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)

以上都是最簡單的,只能實現基本的通信功能,后期會在此基礎上完善,幫助初學者少走彎路,我當時可是學的頭昏眼花-_-||

下篇是采用與服務器完全不同模式的客戶端,同步模式


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM