TCP发送接口(如send(),write()等)的返回值与成功发送到接收端的数据量无直接关系
1. TCP發送接口:send()
? ? ? ? TCP發送數據的接口有send,write,sendmsg。在系統內核中這些函數有一個統一的入口,即sock_sendmsg()。由于TCP是可靠傳輸,所以對TCP的發送接口很容易產生誤解,比如sn = send(...); 錯誤的認為sn的值是表示有sn個字節的數據已經發送到了接收端。其實真相并非如此。
? ? ? ? 我們知道,TCP的發送和接收在在內核(linux)中是有對應的緩沖的:
[cpp]?view plaincopy
2. send()阻塞和非阻塞
前面已說過,sn=send(data)負責將數據拷貝到內核空間,而具體發送是有tcp后續完成(這里面就包括流量控制等)。對已阻塞和非阻塞僅僅是對于數據從用空空間拷貝到內核空間的發送緩沖這段期間而言的。
? ? ? ? 1. 如果發送緩沖剩余空間大于欲發送data的字節數,對于阻塞和非阻塞而言都能成功將數據拷貝至內核緩沖,返回的sn即等于欲發送的數據的字節數。
? ? ? ? 2.如果發送緩沖剩余空間小于欲發送data的字節數,
? ? ? ? ? ? ? ? ? ? a. 那么阻塞模式會進行阻塞,等待內核緩沖的空閑空間,然后繼續將數據拷貝到內核緩沖中,直到全部拷貝為止。返回rn即為data的數據量。
? ? ? ? ? ? ? ? ? ? b. 非阻塞模式,當內核發送緩沖被填滿后,立即返回。rn等于data中已被拷貝到發送緩沖的數據量。
3. 如何判定接收成功接收數據?
? ? ? ? 1.接收端回復應答信息。
? ? ? ? ? ? ? ? 這個方法比較土,但也是比較實用的。
? ? ? ? 2.計算發送端sock已發送數據量
? ? ? ? ? ?可參考:如何判斷TCP數據包是否發送成功?作者提到可以使用?ioctl接口:ioctl(tcp_socket, SIOCOUTQ, &value);
4. 參考:
TCP之send函數研究??
recv send 阻塞和非阻塞??
如何判斷TCP數據包是否發送成功?
總結
以上是生活随笔為你收集整理的TCP发送接口(如send(),write()等)的返回值与成功发送到接收端的数据量无直接关系的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 手把手教你玩转SOCKET模型:重叠I/
- 下一篇: 谈谈网络编程