int recv( SOCKET s, char FAR *buf, int len, int flags);
0、recv會先等待套接字s的發送緩衝中的數據被協議傳送完畢,如果協議在傳送s的發送緩衝中的數據時出現網絡錯誤,那麼recv函數返回SOCKET_ERROR(= -1);
如果s的發送緩衝區中沒有數據或者數據被協議成功發送完畢後,recv再檢查套接字s的接收緩衝區,如果s接收緩衝區中沒有數據或者協議正在接收數據,那麼recv就一直等待,直到協議把數據接收完畢。
當協議把數據接收完畢,recv函數就把s的接收緩衝中的數據copy到buf中(注意協議接收到的數據可能大於buf的長度,所以 在這種情況下要調用幾次recv函數才能把s的接收緩衝中的數據copy完。recv函數僅僅是copy數據,真正的接收數據是協議來完成的)。
1、recv函數返回其實際copy的字節數。
2、如果recv在copy時出錯,比如buf內存不足,那麼它返回SOCKET_ERROR(= -1);
3、如果recv函數在等待協議接收數據時網絡中斷了,通常爲另一端關閉了連接,那麼它返回0。
注意:在Unix系統下,如果recv函數在等待協議接收數據時網絡斷開了,那麼調用recv的進程會接收到一個SIGPIPE信號,進程對該信號的默認處理是進程終止。
TCP中的SIGPIPE信號
在TCP通信中,當通信的雙方中的一方close一個連接時,若另一方接着發數據,根據TCP協議的規定,會收到一個RST響應報文,若再往這個服務器發送數據時,系統會發出一個SIGPIPE信號給進程,告訴進程這個連接已經斷開了,不能再寫入數據。
而引發SIGPIPE信號的寫操作將設置errno爲EPIPE。