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