recv函式的MSG PEEK標誌介紹

2021-07-24 18:56:30 字數 782 閱讀 8123

考慮下面的場景,server向client傳送資料」meta_data\r\n_user_data_」,要求」\r\n」之前的資料meta_data在第一次recv中接收,剩下的recv呼叫讀取user_data部分的資料。因為tcp是stream協議,並且meta_data資料不是定長的,所以沒有辦法保證一次recv呼叫不讀到user_data部分的資料,除非一次讀取乙個字元。這種場景下,recv的msg_peek引數就發揮作用。

recv的原型是ssize_t recv(int s, void *buf, size_t len, int flags); 通常flags都設定為0,此時recv函式讀取tcp buffer中的資料到buf中,並從tcp buffer中移除已讀取的資料。把flags設定為msg_peek,僅把tcp buffer中的資料讀取到buf中,並不把已讀取的資料從tcp buffer中移除,再次呼叫recv仍然可以讀到剛才讀到的資料。

針對上面的場景,recv(fd, buf, nbuf, msg_peek) 檢視資料,檢視」\r\n」的位置pos,再recv(fd, buf, pos+2, 0) 讀取(並移除)資料。

上述場景描述的比較極端,畢竟很多時候,就算在一次recv中讀到了user_data部分的資料,仍可以先把這部分資料儲存起來,新增到後續的recv資料之前,但是如果不同的recv跨越很多函式,儲存資料帶來了額外的複雜度。還可以考慮另外的場景,同乙個埠支援文字協議和二進位制協議,利用msg_peek看一下頭幾個字元,先判斷是文字協議還是二進位制協議,再做請求分發,也是不錯的選擇。當然,真正的recv之前呼叫使用msg_peek導致額外的一次函式呼叫。

奇怪的recv函式

一直有個錯覺,以為recv的函式返回值 0是有資料讀到,0是無資料,0是連線關閉等錯誤。結果最近做了個server,發現檢測不到對端連線關閉,才知道犯了個天大的錯誤,而原因就是recv的返回值的怪異。從下文才知道,即使前面select read控制代碼返回大於0,recv函式返回0竟然是代表連線關閉...

recv函式解析

recv函式 i nt recv socket s,cha r buf,int len,int flags 不論是客戶還是伺服器應用程式都用recv函式從tcp連線的另一端接收資料。該函式的第乙個引數指定接收端套接字描述符 第二個引數指明乙個緩衝區,該緩衝區用來存放recv函式接收到的資料 第三個引...

recv函式的用法詳解

recv函式 int recv socket s,char far buf,int len,int flags 不論是客戶還是伺服器應用程式都用recv函式從tcp連線的另一端接收資料。該函式的第乙個引數指定接收端套接字描述符 第二個引數指明乙個緩衝區,該緩衝區用來存放recv函式接收到的資料 第三...