C#中的System.Net.Sockets内部实现原理
2019獨角獸企業重金招聘Python工程師標準>>>
實現 Berkeley 套接字接口。
MSDN注解:
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?方法可將數據報發送到遠程主機。
若要在執行過程中使用單獨的線程處理通信,請使用下面的方法,這些方法適用于異步操作模式。
-
如果當前使用的是面向連接的協議(如 TCP),則可使用?Socket、BeginConnect?和?EndConnect?方法來連接偵聽主機。通過使用BeginSend?和?EndSend?方法,或者使用?BeginReceive?和?EndReceive?方法,可以進行異步數據通信??梢允褂?BeginAccept?和EndAccept?處理傳入的連接請求。
-
如果您使用的是 UDP 等無連接協議,則可以使用?BeginSendTo?和?EndSendTo?來發送數據報,而使用?BeginReceiveFrom?和EndReceiveFrom?來接收數據報。
如果對一個套接字執行多個異步操作,它們不一定按啟動時的順序完成。
當數據發送和數據接收完成之后,可使用?Shutdown?方法來禁用?Socket。在調用?Shutdown?之后,可調用?Close?方法來釋放與?Socket?關聯的所有資源。
通過?Socket?類,您可以使用?SetSocketOption?方法來配置?Socket??梢允褂?GetSocketOption?方法來檢索這些設置。
| 如果要編寫相對簡單的應用程序,而且不需要最高的性能,則可以考慮使用?TcpClient、TcpListener?和?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);??這個性能上會好很多。
轉載于:https://my.oschina.net/u/185531/blog/900598
總結
以上是生活随笔為你收集整理的C#中的System.Net.Sockets内部实现原理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [elixir! #0037] Agen
- 下一篇: 当前页面怎么调用子集iframe页面的方