recv函數解析

recv函數

int recv( SOCKET s, charFAR *buf, int len, int flags);

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

第二個參數指明一個緩衝區,該緩衝區用來存放recv函數接收到的數據;

第三個參數指明buf的長度;

第四個參數一般置0。

這裏只描述同步Socket的recv函數的執行流程。當應用程序調用recv函數時,

(1)recv先等待s的發送緩衝中的數據被協議傳送完畢,如果協議在傳送s的發送緩衝中的數據時出現網絡錯誤,那麼recv函數返回SOCKET_ERROR,

(2)如果s的發送緩衝中沒有數據或者數據被協議成功發送完畢後,recv先檢查套接字s的接收緩衝區,如果s接收緩衝區中沒有數據或者協議正在接收數據,那麼recv就一直等待,直到協議把數據接收完畢。當協議把數據接收完畢,recv函數就把s的接收緩衝中的數據copy到buf中(注意協議接收到的數據可能大於buf的長度,所以在這種情況下要調用幾次recv函數才能把s的接收緩衝中的數據copy完。recv函數僅僅是copy數據,真正的接收數據是協議來完成的),

recv函數返回其實際copy的字節數。如果recv在copy時出錯,那麼它返回SOCKET_ERROR;如果recv函數在等待協議接收數據時網絡中斷了,那麼它返回0。


默認 socket是阻塞的

解阻塞與非阻塞recv返回值沒有區分,都是
<0出錯
=0連接關閉
>0接收到數據大小,

特別:返回值<0時並且(errno ==EINTR || errno == EWOULDBLOCK || errno ==EAGAIN)的情況下認爲連接是正常的,繼續接收。
只是阻塞模式下recv會阻塞着接收數據,非阻塞模式下如果沒有數據會返回,不會阻塞着讀,因此需要循環讀取)。

返回說明:
成功執行時,返回接收到的字節數。另一端已關閉則返回0。失敗返回-1,errno被設爲以下的某個值
EAGAIN:套接字已標記爲非阻塞,而接收操作被阻塞或者接收超時
EBADF:sock不是有效的描述詞
ECONNREFUSE:遠程主機阻絕網絡連接
EFAULT:內存空間訪問出錯
EINTR:操作被信號中斷
EINVAL:參數無效
ENOMEM:內存不足
ENOTCONN:與面向連接關聯的套接字尚未被連接上
ENOTSOCK:sock索引的不是套接字

當返回值是0時,爲正常關閉連接;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章