C#中的System.Net.Sockets內部實現原理

實現 Berkeley 套接字接口。編程

MSDN註解:c#

Socket 類爲網絡通訊提供了一套豐富的方法和屬性。Socket 類容許您使用 ProtocolType 枚舉中所列出的任何一種協議執行異步和同步數據傳輸。Socket 類遵循異步方法的 .NET Framework 命名模式;例如,同步 Receive 方法對應於異步 BeginReceive 和 EndReceive 方法。服務器

若是應用程序在執行期間只須要一個線程,請使用下面的方法,這些方法適用於同步操做模式。網絡

  • 若是當前使用的是面向鏈接的協議(如 TCP),則服務器可使用 Listen 方法偵聽鏈接。Accept 方法處理任何傳入的鏈接請求,並返回可用於與遠程主機進行數據通訊的 Socket。可使用此返回的 Socket 來調用 Send 或 Receive 方法。若是要指定本地 IP 地址和端口號,請在調用 Listen 方法以前先調用 Bind 方法。若是您但願基礎服務提供程序爲您分配可用端口,請使用端口號 0。若是但願鏈接到偵聽主機,請調用 Connect 方法。若要進行數據通訊,請調用 Send 或 Receive 方法。框架

  • 若是當前使用的是無鏈接協議(如 UDP),則根本不須要偵聽鏈接。調用 ReceiveFrom 方法可接受任何傳入的數據報。使用 SendTo 方法可將數據報發送到遠程主機。異步

若要在執行過程當中使用單獨的線程處理通訊,請使用下面的方法,這些方法適用於異步操做模式。socket

  • 若是當前使用的是面向鏈接的協議(如 TCP),則可以使用 SocketBeginConnect 和 EndConnect 方法來鏈接偵聽主機。經過使用BeginSend 和 EndSend 方法,或者使用 BeginReceive 和 EndReceive 方法,能夠進行異步數據通訊。可使用 BeginAccept 和EndAccept 處理傳入的鏈接請求。tcp

  • 若是您使用的是 UDP 等無鏈接協議,則可使用 BeginSendTo 和 EndSendTo 來發送數據報,而使用 BeginReceiveFrom 和EndReceiveFrom 來接收數據報。函數

若是對一個套接字執行多個異步操做,它們不必定按啓動時的順序完成。性能

當數據發送和數據接收完成以後,可以使用 Shutdown 方法來禁用 Socket。在調用 Shutdown 以後,可調用 Close 方法來釋放與 Socket 關聯的全部資源。

經過 Socket 類,您可使用 SetSocketOption 方法來配置 Socket。可使用 GetSocketOption 方法來檢索這些設置。

Note注意

若是要編寫相對簡單的應用程序,並且不須要最高的性能,則能夠考慮使用 TcpClientTcpListener 和 UdpClient。這些類爲 Socket 通訊提供了更簡單、對用戶更友好的接口。

Windows Mobile for Pocket PC, Windows Mobile for Smartphone, Windows CE 平臺說明: 並不是全部設備的操做系統會支持所有的套接字選項。

 

異步讀取數據

/// <summary>
///     異步讀取數據
/// </summary>
 private void AsyncRead()
   {
            
      var remote = (EndPoint) new IPEndPoint(0, 0);
      _socket.BeginReceiveFrom(_buffer, 0, _buffer.Length, SocketFlags.None, ref remote, AsyncReadCallback,null);           
            
        }

/// <summary>
///     異步讀回調函數
/// </summary>
 /// <param name="ar"></param>
 public void AsyncReadCallback(IAsyncResult ar)
   {
      var remote = (EndPoint) new IPEndPoint(0, 0);
     var size = _socket.EndReceiveFrom(ar, ref remote);

      if (null != _callback && size > 0)
           {
                    _callback(this, _buffer, 0, size, remote as IPEndPoint);
            }
            else
            {
                    return;
            }

           //休眠15毫秒,防止使用CPU太高
             Thread.Sleep(15);
           

            //繼續進行異步讀取數據
            AsyncRead();
        }

CSDN裏面有人討論說,Net裏的Socket的異步操做就是用完成端口來實現的,針對TCP的高效服務端模型(IOCP)。另外,在.Net中,System.Net.Sockets 命名空間爲須要嚴密控制網絡訪問的開發人員,提供了 Windows Sockets (Winsock) 接口的託管實現。針對Socket編程,.NET 框架的 Socket 類是 Winsock32 API 提供的套接字服務的託管代碼版本。

 

討論諮詢的帖子;http://bbs.csdn.net/topics/390830639

彙總:

我看都沒C#的IOCP例程,不知是否C#開發服務器已經不須要考慮作IOCP形式?



跟c#沒有關係,是.net framework封裝了IOCP,你應該使用 TcpListener/TcpClient類,而不是Socket類!

正解,tcpclient內部已經實現了iocp.用reflector看代碼就知道了,他用的是wsarecv方法。

其實你用socket的BeginRecive也同樣,它也是調用的wsarecv

我也看到了源碼裏面調用的是WSARecv並且傳入了WSAOVERLAPPED結構。

SocketAsyncEventArgs 用這個就是IOCP
要配合Socket    m_Socket.ReceiveAsync(m_ReceiveEventArgs); 這個方法

Socket BeginReceive 這個有個缺點就是要一直裝箱拆箱,因此在NET4.0就增長了m_Socket.ReceiveAsync(m_ReceiveEventArgs);  這個性能上會好不少。

相關文章
相關標籤/搜索