C# TCP socket發送大數據包時,接收端和發送端數據不一致 服務端接收Receive不完全


 

簡單的c# TCP通訊(TcpListener)

C# 的TCP Socket (同步方式)

C# 的TCP Socket (異步方式)

C# 的tcp Socket設置自定義超時時間

C# TCP socket發送大數據包時,接收端和發送端數據不一致 服務端接收Receive不完全

 

 

在發送端,一次發送200k個字節,在接收端,一次接收200k個字節,

但是在接收端,經常會出現 socket.receive 接收不全的情況 ,

 

偶爾接收的包也是正常的,用Wireshark抓包發現,每次發送都分成了多個1514字節長的數據包,一次數據有多個數據包,

 

標准以太網幀長度下限為:64 字節

標准以太網幀長度上限為:1518 字節

 

每個數據包含1448字節有效數據

這也正好解釋了為什么接收數據包不完整時接收到的長度都正好是1448的倍數如1448,2896,4344等等

 

所以需要多次接收然后對數據進行合並,代碼如下:

 

Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
listener.ReceiveBufferSize = 100 * 1024 * 1024;
listener.ReceiveTimeout = 100000;
listener.Bind(localEndPoint);

Socket sock = listener.Accept();
byte[] bs = new byte[1024*1024];
int ilen = sock.Receive(bs);
uint length = ByteTouint(bs, 3, 4);
while (ilen < length)
{
    int ii = sock.Receive(bs, ilen, 500 * 1024, SocketFlags.None);
    ilen = ilen + ii;
}

這樣接收的內容就對了。

 

 

異步方式里  C# 的TCP Socket (異步方式) ,在ReadCallback里

while (bytesRead < state.bodybuffer.Length)
                {
                    int ii = handler.Receive(state.bodybuffer, bytesRead, state.bodybuffer.Length - bytesRead, SocketFlags.None);
                    bytesRead = bytesRead + ii;
                }

 

 

作者:車小胖
鏈接:https://www.zhihu.com/question/21524257/answer/118266374
來源:知乎
著作權歸作者所有,轉載請聯系作者獲得授權。

最早的以太網工作方式:載波多路復用/沖突檢測CSMA/CD,因為網絡是共享的,即任何一個節點發送數據之前,先要偵聽線路上是否有數據在傳輸,如果有,需要等待,如果線路可用,才可以發送。

假設A發出第一個bit位,到達B,而B也正在傳輸第一個bit位,於是產生沖突,沖突信號得讓A在完成最后一個bit位之前到達A,這個一來一回的時間間隙slot time是57.6μs.


在10Mbps的網絡中,在57.6μs的時間內,能夠傳輸576個bit,所以要求以太網幀最小長度為576個bits,從而讓最極端的碰撞都能夠被檢測到。這個576bit換算一下就是72個字節,去掉8個字節的前導符和幀開始符,以太網幀的最小長度為64字節。


如果說以太網幀的最小長度64byte是由CSMA/CD限制所致,那最大長度1500byte又是處於什么考慮的呢?

IP頭total length為兩個byte,理論上IP packet可以有65535 byte,加上Ethernet Frame頭和尾,可以有65535 +14 + 4 = 65553 byte。如果在10Mbps以太網上,將會占用共享鏈路長達50ms,這將嚴重影響其它主機的通信,特別是對延遲敏感的應用是無法接受的。

由於線路質量差而引起的丟包,發生在大包的概率也比小包概率大得多,所以大包在丟包率較高的線路上不是一個好的選擇。

但是如果選擇一個比較小的長度,傳輸效率又不高,拿TCP應用來說,如果選擇以太網長度為218byte,TCP payload = 218 - Ethernet Header -IP Header - TCP Header=218-18 - 20 -20= 160 byte

那有效傳輸效率=160/218= 73%

而如果以太網長度為1518,那有效傳輸效率=1460/1518=96%

通過比較,選擇較大的幀長度,有效傳輸效率更高,而更大的幀長度同時也會造成上述的問題,於是最終選擇一個折衷的長度:1518 byte ! 對應的IP packet 就是 1500 byte,這就是最大傳輸單元MTU的由來。


免責聲明!

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



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