網(wǎng)絡編程send()和recv()詳解

1.send 函數(shù)

int?send(?SOCKET?s, const?char?FAR?*buf,

int?len, int?flags?);

不論是客戶還是服務器應用程序都用send函數(shù)來向TCP連接的另一端發(fā)送數(shù)據(jù)??蛻舫绦蛞话阌胹end函數(shù)向服務器發(fā)送請求,而服務器則通常用send函數(shù)來向客戶程序發(fā)送應答。

該函數(shù)的第一個參數(shù)指定發(fā)送端套接字描述符;

第二個參數(shù)指明一個存放應用程序要發(fā)送數(shù)據(jù)的緩沖區(qū);

第三個參數(shù)指明實際要發(fā)送的數(shù)據(jù)的字節(jié)數(shù);

第四個參數(shù)一般置0。

這里只描述同步Socket的send函數(shù)的執(zhí)行流程。當調(diào)用該函數(shù)時,

(1)send先比較待發(fā)送數(shù)據(jù)的長度len和套接字s的發(fā)送緩沖的長度,?如果len大于s的發(fā)送緩沖區(qū)的長度,該函數(shù)返回SOCKET_ERROR;

(2)如果len小于或者等于s的發(fā)送緩沖區(qū)的長度,那么send先檢查協(xié)議是否正在發(fā)送s的發(fā)送緩沖中的數(shù)據(jù),如果是就等待協(xié)議把數(shù)據(jù)發(fā)送完,如果協(xié)議

還沒有開始發(fā)送s的發(fā)送緩沖中的數(shù)據(jù)或者s的發(fā)送緩沖中沒有數(shù)據(jù),那么send就比較s的發(fā)送緩沖區(qū)的剩余空間和len

(3)如果len大于剩余空間大小,send就一直等待協(xié)議把s的發(fā)送緩沖中的數(shù)據(jù)發(fā)送完

(4)如果len小于剩余?空間大小,send就僅僅把buf中的數(shù)據(jù)copy到剩余空間里(注意并不是send把s的發(fā)送緩沖中的數(shù)據(jù)傳到連接的另一端的,而是協(xié)議傳的,send僅僅是把buf中的數(shù)據(jù)copy到s的發(fā)送緩沖區(qū)的剩余空間里)。

如果send函數(shù)copy數(shù)據(jù)成功,就返回實際copy的字節(jié)數(shù),如果send在copy數(shù)據(jù)時出現(xiàn)錯誤,那么send就返回SOCKET_ERROR;如果send在等待協(xié)議傳送數(shù)據(jù)時網(wǎng)絡斷開的話,那么send函數(shù)也返回SOCKET_ERROR。

要注意send函數(shù)把buf中的數(shù)據(jù)成功copy到s的發(fā)送緩沖的剩余空間里后它就返回了,但是此時這些數(shù)據(jù)并不一定馬上被傳到連接的另一端。如

果協(xié)議在后續(xù)的傳送過程中出現(xiàn)網(wǎng)絡錯誤的話,那么下一個Socket函數(shù)就會返回SOCKET_ERROR。(每一個除send外的Socket函數(shù)在

執(zhí)?行的最開始總要先等待套接字的發(fā)送緩沖中的數(shù)據(jù)被協(xié)議傳送完畢才能繼續(xù),如果在等待時出現(xiàn)網(wǎng)絡錯誤,那么該Socket函數(shù)就返

回?SOCKET_ERROR)

注意:在Unix系統(tǒng)下,如果send在等待協(xié)議傳送數(shù)據(jù)時網(wǎng)絡斷開的話,調(diào)用send的進程會接收到一個SIGPIPE信號,進程對該信號的默認處理是進程終止。

通過測試發(fā)現(xiàn),異步socket的send函數(shù)在網(wǎng)絡剛剛斷開時還能發(fā)送返回相應的字節(jié)數(shù),同時使用select檢測也是可寫的,但是過幾秒鐘之后,再send就會出錯了,返回-1。select也不能檢測出可寫了。

2. recv函數(shù)

int?recv(?SOCKET?s, char?FAR?*buf, int?len, int?flags);

不論是客戶還是服務器應用程序都用recv函數(shù)從TCP連接的另一端接收數(shù)據(jù)。該函數(shù)的第一個參數(shù)指定接收端套接字描述符;

第二個參數(shù)指明一個緩沖區(qū),該緩沖區(qū)用來存放recv函數(shù)接收到的數(shù)據(jù);

第三個參數(shù)指明buf的長度;

第四個參數(shù)一般置0。

這里只描述同步Socket的recv函數(shù)的執(zhí)行流程。當應用程序調(diào)用recv函數(shù)時,

(1)recv先等待s的發(fā)送緩沖中的數(shù)據(jù)被協(xié)議傳送完畢,如果協(xié)議在傳送s的發(fā)送緩沖中的數(shù)據(jù)時出現(xiàn)網(wǎng)絡錯誤,那么recv函數(shù)返回SOCKET_ERROR,

(2)如果s的發(fā)送緩沖中沒有數(shù)據(jù)或者數(shù)據(jù)被協(xié)議成功發(fā)送完畢后,recv先檢查套接字s的接收緩沖區(qū),如果s接收緩沖區(qū)中沒有數(shù)據(jù)或者協(xié)議正在接收數(shù)

據(jù),那么recv就一直等待,直到協(xié)議把數(shù)據(jù)接收完畢。當協(xié)議把數(shù)據(jù)接收完畢,recv函數(shù)就把s的接收緩沖中的數(shù)據(jù)copy到buf中(注意協(xié)議接收到的數(shù)據(jù)可能大于buf的長度,所以?在這種情況下要調(diào)用幾次recv函數(shù)才能把s的接收緩沖中的數(shù)據(jù)copy完。recv函數(shù)僅僅是copy數(shù)據(jù),真正的接收數(shù)據(jù)是協(xié)議來完成的),

recv函數(shù)返回其實際copy的字節(jié)數(shù)。如果recv在copy時出錯,那么它返回SOCKET_ERROR;如果recv函數(shù)在等待協(xié)議接收數(shù)據(jù)時網(wǎng)絡中斷了,那么它返回0。

注意:在Unix系統(tǒng)下,如果recv函數(shù)在等待協(xié)議接收數(shù)據(jù)時網(wǎng)絡斷開了,那么調(diào)用recv的進程會接收到一個SIGPIPE信號,進程對該信號的默認處理是進程終止。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • http://python.jobbole.com/85231/ 關于專業(yè)技能寫完項目接著寫寫一名3年工作經(jīng)驗的J...
    燕京博士閱讀 7,787評論 1 118
  • socket通信原理 socket又被叫做套接字,它就像連接到兩端的插座孔一樣,通過建立管道,將兩個不同的進程之間...
    jiodg45閱讀 1,227評論 0 1
  • 1、TCP狀態(tài)linux查看tcp的狀態(tài)命令:1)、netstat -nat 查看TCP各個狀態(tài)的數(shù)量2)、lso...
    北辰青閱讀 9,700評論 0 11
  • 肖氏醫(yī)館雖然開業(yè)的時間并不長,但是在長安城里的名聲卻已然不小。 年近古稀的肖大夫,從醫(yī)足有五十余載,什么大大小小、...
    泥藏風閱讀 606評論 3 3
  • 今天早起,聽完課程,易老師問,你知道你過去的每一天,時間都花在哪兒嗎? 回顧過去我過的每一天,似乎知道又似乎不知道...
    悠然小霞閱讀 233評論 2 2

友情鏈接更多精彩內(nèi)容