1. 程式人生 > >linux send與recv函式詳解

linux send與recv函式詳解

1 #include <sys/socket.h> 2 ssize_t recv(int sockfd, void *buff, size_t nbytes, int flags); 3 ssize_t send(int sockfd, const void *buff, size_t nbytes, int flags); 複製程式碼

recv 和send的前3個引數等同於read和write。 flags引數值為0或:

      flags    說明    recv    send           MSG_DONTROUTE    繞過路由表查詢            •           MSG_DONTWAIT    僅本操作非阻塞        •          •           MSG_OOB        傳送或接收帶外資料      •      •           MSG_PEEK      窺看外來訊息      •                MSG_WAITALL      等待所有資料       •        

1. send解析 sockfd:指定傳送端套接字描述符。 buff:    存放要傳送資料的緩衝區 nbytes:  實際要改善的資料的位元組數 flags:   一般設定為0 1) send先比較傳送資料的長度nbytes和套接字sockfd的傳送緩衝區的長度,如果nbytes > 套接字sockfd的傳送緩衝區的長度, 該函式返回SOCKET_ERROR; 2) 如果nbtyes <= 套接字sockfd的傳送緩衝區的長度,那麼send先檢查協議是否正在傳送sockfd的傳送緩衝區中的資料,如果是就等待協議把資料傳送完,如果協議還沒有開始傳送sockfd的傳送緩衝區中的資料或者sockfd的傳送緩衝區中沒有資料,那麼send就比較sockfd的傳送緩衝區的剩餘空間和nbytes 3) 如果 nbytes > 套接字sockfd的傳送緩衝區剩餘空間的長度,send就一起等待協議把套接字sockfd的傳送緩衝區中的資料傳送完 4) 如果 nbytes < 套接字sockfd的傳送緩衝區剩餘空間大小,send就僅僅把buf中的資料copy到剩餘空間裡(注意並不是send把套接字sockfd的傳送緩衝區中的資料傳到連線的另一端的,而是協議傳送的,send僅僅是把buf中的資料copy到套接字sockfd的傳送緩衝區的剩餘空間裡)。 5) 如果send函式copy成功,就返回實際copy的位元組數,如果send在copy資料時出現錯誤,那麼send就返回SOCKET_ERROR; 如果在等待協議傳送資料時網路斷開,send函式也返回SOCKET_ERROR。 6) send函式把buff中的資料成功copy到sockfd的改善緩衝區的剩餘空間後它就返回了,但是此時這些資料並不一定馬上被傳到連線的另一端。如果協議在後續的傳送過程中出現網路錯誤的話,那麼下一個socket函式就會返回SOCKET_ERROR。(每一個除send的socket函式在執行的最開始總要先等待套接字的傳送緩衝區中的資料被協議傳遞完畢才能繼續,如果在等待時出現網路錯誤那麼該socket函式就返回SOCKET_ERROR) 7) 在unix系統下,如果send在等待協議傳送資料時網路斷開,呼叫send的程序會接收到一個SIGPIPE訊號,程序對該訊號的處理是程序終止。 2.recv函式 sockfd: 接收端套接字描述符 buff:   用來存放recv函式接收到的資料的緩衝區 nbytes: 指明buff的長度 flags:   一般置為0 1) recv先等待s的傳送緩衝區的資料被協議傳送完畢,如果協議在傳送sock的傳送緩衝區中的資料時出現網路錯誤,那麼recv函式返回SOCKET_ERROR 2) 如果套接字sockfd的傳送緩衝區中沒有資料或者資料被協議成功傳送完畢後,recv先檢查套接字sockfd的接收緩衝區,如果sockfd的接收緩衝區中沒有資料或者協議正在接收資料,那麼recv就一起等待,直到把資料接收完畢。當協議把資料接收完畢,recv函式就把s的接收緩衝區中的資料copy到buff中(注意協議接收到的資料可能大於buff的長度,所以在這種情況下要呼叫幾次recv函式才能把sockfd的接收緩衝區中的資料copy完。recv函式僅僅是copy資料,真正的接收資料是協議來完成的) 3) recv函式返回其實際copy的位元組數,如果recv在copy時出錯,那麼它返回SOCKET_ERROR。如果recv函式在等待協議接收資料時網路中斷了,那麼它返回0。 4) 在unix系統下,如果recv函式在等待協議接收資料時網路斷開了,那麼呼叫 recv的程序會接收到一個SIGPIPE訊號,程序對該訊號的預設處理是程序終止。