c#非同步socket

來源:互聯網
上載者:User

.NET Socket開發之非同步Socket

  在基於.NET的網路服務端的開發中,我們用到和聽到的最多的恐怕就是非同步Socket了。非同步Socket的效能比同步高出很多,但是編寫代碼比較複雜。因此非同步Socket也是網路上討論比較多的話題。

  今天,我們就來討論一下如何用非同步Socket開發網路應用。在此之前我們先討論兩個問題。

  一、非同步Socket是如何工作的:

  那非同步Socket是如何工作的呢?我以接收一條訊息來說明這個問題。首先,程式向系統投遞一個接收資料的請求,並為其指定一個資料緩衝區和回呼函數,回呼函數用來指示當資料到達後將如何處理,然後我們的程式繼續執行下去,當有資料到達的時候,系統將資料讀入緩衝區,並執行回呼函數,處理這條訊息。我們並不需要關心這條訊息何時到達。

  二、什麼情況下我們用非同步Socket:

  有些人認為,非同步Socket的效能比同步Socket的效能高很多,應該在各種環境下都用非同步Socket,其實不然。在某些環境下面。非同步反到比同步的效能低,那麼在哪些情況下會這樣呢?

  1、 用戶端Socket。

  2、 服務端串連數比較少。

  3、 串連數很多,但都是短串連。

  在這些環境下,我們用同步Socket不但可以簡化代碼,而且效能並不會比非同步Socket低。但在服務端串連比較多而且是長串連的情況下,我們就要使用非同步Socket。

  現在我們來看看如何用非同步Socket編程。

  首先,我們要建立一個Socket用來監聽:

  Socket _listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

      IPEndPoint localEP = new IPEndPoint(_address, _port);

    _listener.Bind(localEP);  

     _listener.Listen(100);   然後建立一個線程來處理用戶端串連請求:

  我們再來看看回呼函數的定義:

  private void ReceiveCallBack(IAsyncResult ar)

  {       

         UserInfo info = (UserInfo)ar.AsyncState;

   Socket handler = info.socket;

     int readCount = 0;

   try

        {         

          readCount = handler.EndReceive(ar);//調用這個函數來結束本次接收並返回接收到的資料長度。

   }       

        catch (SocketException)//出現Socket異常就關閉串連

    {         

              CloseSocket(info);//這個函數用來關閉用戶端串連

       return;

   }

   catch       {       }

    if (readCount > 0)

   {

      byte[] buffer = new byte[readCount];

      Buffer.BlockCopy(info.Buffer, 0, buffer, 0, readCount);

      Analyzer(info, buffer);//這個函數用來處理接收到的資訊。

     try

    {

      handler.BeginReceive(info.Buffer, 0, info.Buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallBack), info);//向系統投遞下一個接收請求         

            }

    catch (SocketException) //出現Socket異常就關閉串連         

            {           

                   CloseSocket(info);  

    }  

    catch

    {         

             }

            }       

          else //如果接收到0位元組的資料說明用戶端關閉了Socket,那我們也要關閉Socket

    {         

               CloseSocket(info);

     }  

    }   

     接下來我們看看如何發送資料給用戶端:

    public void Send(Socket socket, byte message)

    {       

                  try       

                 {         

           info.socket.BeginSend(message, 0, _byte.Length, SocketFlags.None, new AsyncCallback(SendCallBack), info);//這裡向系統投遞一個發送資料的請求,並指定一個回呼函數。       

                 }       

                 catch (SocketException ex)

      {         

                      CloseSocket(info);  

        }       

                catch       

                {       }

        }   定義發送回呼函數:

    private void SendCallBack(IAsyncResult ar)  

     {       

                 UserInfo info = (UserInfo)ar.AsyncState;

       try 

      {         

                       info.socket.EndSend(ar);//調用這個函數來結束本次發送。

      }       

                catch       

               {       

}     }   

好了,整個監聽、接收、發送的過程就完成了,很簡單吧。現在需要說明的是,我在這裡接收用戶端串連的Accept是用的同步的,我個人認為在這裡用同步的會比用非同步好一些。因為這樣代碼簡單而且沒有效能上的損失。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.