歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Linux send與recv函數詳解

#include <sys/socket.h>
ssize_t recv(int sockfd, void *buff, size_t nbytes, int flags);
ssize_t send(int sockfd, const void *buff, size_t nbytes, int flags);

flags 說明 recv send MSG_DONTROUTE 繞過路由表查找   • MSG_DONTWAIT 僅本操作非阻塞 • MSG_OOB     發送或接收帶外數據 • • MSG_PEEK   窺看外來消息 •   MSG_WAITALL   等待所有數據 •  

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

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信號,進程對該信號的默認處理是進程終止。

Copyright © Linux教程網 All Rights Reserved