1 while(rs)
2 {
3 buflen = recv(activeevents[i].data.fd, buf, sizeof(buf), 0);
4 if(buflen < 0)
5 {
6 // 因爲是非阻塞的模式,因此當errno爲EAGAIN時,表示當前緩衝區已無數據可讀
7 // 在這裏就看成是該次事件已處理
8 if(errno == EAGAIN)
9 break;
10 else
11 return;
12 }
13 else if(buflen == 0)
14 {
15 // 這裏表示對端的socket已正常關閉.
16 }
17 if(buflen != sizeof(buf))
18 rs = 0;
19 else
20 rs = 1;// 須要再次讀取
21 }
註釋
本函數用於已鏈接的數據報或流式
套接口進行數據的接收。
對於數據報類
套接口,隊列中第一個數據報中的數據被
解包,但最多不超過
緩衝區的大小。若是數據報大於
緩衝區,那麼緩衝區中只有數據報的前面部分,其餘的數據都丟失了,而且recv()函數返回WSAEMSGSIZE錯誤。若是沒有數據待讀,那麼除非是非阻塞模式,否則的話
套接口將一直等待數據的到來,此時將返回SOCKET_ERROR錯誤,
錯誤代碼是WSAEWOULDBLOCK。用
select()或WSAAsynSelect()能夠獲知什麼時候數據到達。
若是
套接口爲SOCK_STREAM類型,而且遠端「優雅」地停止了鏈接,那麼recv()一個數據也不讀取,當即返回。若是當即被強制停止,那麼recv()將以WSAECONNRESET錯誤失敗返回。在
套接口的所設選項之上,還可用標誌位flag來影響函數的執行方式。也就是說,本函數的語義既取決於
套接口選項,也取決於標誌位參數。標誌位可取下列值:
值意義
windows版本:
第四個參數:
MSG_PEEK 查看當前數據。數據將被複制到
緩衝區中,但並不從輸入隊列中刪除。
MSG_OOB 處理
帶外數據(參見2.2.3節具體討論)。
返回值:
若無錯誤發生,recv()返回讀入的字節數。若是鏈接已停止,返回0。不然的話,返回SOCKET_ERROR錯誤,
應用程序可經過WSAGetLastError()獲取相應
錯誤代碼。
WSANOTINITIALISED:在使用此API以前應首先成功地調用WSAStartup()。
WSAENETDOWN:WINDOWS
套接口實現檢測到網絡子系統失效。
WSAEINTR:阻塞進程被WSACancelBlockingCall()取消。
WSAEINPROGRESS:一個阻塞的WINDOWS
套接口調用正在運行中。
WSAEOPNOTSUPP:指定了MSG_OOB,但
套接口不是SOCK_STREAM類型的。
WSAESHUTDOWN:
套接口已被關閉。當一個
套接口以0或2的how參數調用shutdown()關閉後,沒法再用recv()接收數據。
WSAEWOULDBLOCK:
套接口標識爲非阻塞模式,但接收操做會產生阻塞。
WSAEMSGSIZE:數據報太大沒法所有裝入
緩衝區,故被剪切。
WSAEINVAL:
套接口未用bind()進行捆綁。
WSAECONNABORTED:因爲超時或其餘緣由,虛電路失效。
WSAECONNRESET:遠端強制停止了虛電路。
linux版本:
第四個參數:
MSG_DONTROUTE 繞過路由表查找。
MSG_DONTWAIT 僅本操做非阻塞。
MSG_OOB 發送或接收帶外數據。
MSG_PEEK 窺看外來消息。
MSG_WAITALL 等待全部數據。
返回值:
若無錯誤發生,recv()返回讀入的字節數。若是鏈接已停止,返回0。若是發生錯誤,返回-1,
應用程序可經過perror()獲取相應錯誤信息。