Send函式和Recv函式解析

2021-09-30 07:17:55 字數 4300 閱讀 6031

send函式和

recv

函式解析

1. send函式 i

nt send( socket s, const char far *buf, int len, int flags );  

不論是客戶

端還是伺服器

端應用程式都用send

函式來向

tcp連線的另一端傳送資料。

客戶端程式一般用send

函式向伺服器傳送請求,而伺服器則通常用

send

函式來向客戶程式傳送應答。

該函式的:

第乙個引數指定傳送端套接字描述符;

第二個引數指明乙個存放應用程式要傳送資料的緩衝區;

第三個引數指明實際要傳送的資料的位元組數;

第四個引數一般置0。

這裡只描述同步socket

的send

函式的執行流程。當呼叫該函式時,

send

先比較待傳送資料的長度

len和套接字s的

傳送緩衝的長度

,如果len大於s

的傳送緩衝區的長度,該函式返回

socket_error

;如果len

小於或者等於

s的傳送緩衝區的長度,那麼

send

先檢查協議 是否正在傳送

s的傳送緩衝中的資料,如果是就等待協議把資料傳送完,如果協議還沒有開始傳送

s的傳送緩衝中的資料或者

s的傳送緩衝中沒有資料,那麼 

send

就比較s

的傳送緩衝區的剩餘空間和

len,如果

len大於剩餘空間大小

send

就一直等待協議把

s的傳送緩衝中的資料傳送完,如果

len小於剩餘 空間大小

send

就僅僅把

buf中的資料

copy

到剩餘空間裡(

注意並不是send把s

的傳送緩衝中的資料傳到連線的另一端的,而是協議傳的,

send

僅僅是把

buf中的資料

copy到s

的傳送緩衝區的剩餘空間裡

)。如果send

函式copy

資料成功,就返回實際

copy

的位元組數,如果

send

在copy

資料時出現錯誤,那麼

send

就返回socket_error

;如果send

在等待協議傳送資料時網路斷開的話,那麼

send

函式也返回

socket_error。

要注意send

函式把buf

中的資料成功

copy到s

的傳送緩衝的剩餘空間裡後它就返回了,但是此時這些資料並不一定馬上被傳到連線的另一端

。如果協議在後續的傳送過程**現網路錯誤的話,那麼下乙個socket

函式就會返回

socket_error

。(每乙個除

send

外的socket

函式在執 行的最開始總要先等待套接字的傳送緩衝中的資料被協議傳送完畢才能繼續,如果在等待時出現網路錯誤,那麼該

socket

函式就返回 

socket_error)

注意:在unix

系統下,如果

send

在等待協議傳送資料時網路斷開的話,呼叫

send

的程序會接收到乙個

sigpipe

訊號,程序對該訊號的預設處理是程序終止。

send函式的返回值有三類:

(1)返回值=0:

(2)返回值<0

:傳送失敗,錯誤原因存於全域性變數

errno中

(3)返回值》0

:表示傳送的位元組數(實際上是拷貝到傳送緩衝中的位元組數)

錯誤**:

ebadf 引數

s 非合法的

socket

處理**。

efault 引數中有一指標指向無法訪問的記憶體空間

enotsock 引數

s為一檔案描述詞,非

socket

。eintr 被訊號所中斷。

eagain 此操作會令程序阻斷,但引數s的

socket

為不可阻斷。

enobufs 系統的緩衝記憶體不足

enomem 核心記憶體不足

einval 傳給系統呼叫的引數不正確。

2.  

recv函式 i

nt recv( socket s,     char far *buf,      int len,     int flags     );   

不論是客戶

端還是伺服器

端應用程式都用recv

函式從tcp

連線的另一端接收資料。

該函式的:

第乙個引數指定接收端套接字描述符;

第二個引數指明乙個緩衝區,該緩衝區用來存放recv

函式接收到的資料;

第三個引數指明buf

的長度;

第四個引數一般置0。

這裡只描述同步socket

的recv

函式的執行流程。當應用程式呼叫

recv

函式時,

recv

先等待s

的傳送緩衝 中的資料被協議傳送完畢,如果協議在傳送

s的傳送緩衝中的資料時出現網路錯誤,那麼

recv

函式返回

socket_error

,如果s

的傳送緩衝中沒有數 據或者資料被協議成功傳送完畢後,

recv

先檢查套接字

s的接收緩衝區,如果

s接收緩衝區中沒有資料或者協議正在接收資料,那麼

recv

就一直等待,只到 協議把資料接收完畢。當協議把資料接收完畢,

recv

函式就把

s的接收緩衝中的資料

copy

到buf

中(注意協議接收到的資料可能大於buf

的長度,所以 在這種情況下要呼叫幾次

recv

函式才能把

s的接收緩衝中的資料

copy

完。recv

函式僅僅是

copy

資料,真正的接收資料是協議來完成的

),recv

函式返回其實際

copy

的位元組數。如果

recv

在copy

時出錯,那麼它返回

socket_error

;如果recv

函式在等待協議接收資料時網路中斷了,那麼它返回0。

注意:在unix

系統下,如果

recv

函式在等待協議接收資料時網路斷開了,那麼呼叫

recv

的程序會接收到乙個

sigpipe

訊號,程序對該訊號的預設處理是程序終止。

預設情況下socket

是阻塞的。

阻塞與非阻塞recv

返回值沒有區別,都是:

<0 出錯

=0 對方呼叫了

close api來

關閉連線

>0 接收到

的資料大小,

特別地:返回值<0

時並且(errno == eintr || errno == ewouldblock || errno == eagain)

的情況下認為連線是正常的,繼續接收。

只是阻塞模式下recv

會一直阻塞直到接收到資料,非阻塞模式下如果沒有資料就會返回,不會阻塞著讀,因此需要迴圈讀取)。

返回說明:   

(1)成功執行時,返回接收到的位元組數。

(2)若另一端已關閉連線則返回

0,這種關閉是對方主動且正常的關閉

(3)失敗返回-1,

errno

被設為以下的某個值   

eagain:套接字已標記為非阻塞,而接收操作被阻塞或者接收超時

ebadf:

sock

不是有效的描述詞

econnrefuse:遠端主機阻絕網路連線

efault:記憶體空間訪問出錯

eintr:操作被訊號中斷

einval:引數無效

enomem:記憶體不足

enotconn:與面向連線關聯的套接字尚未被連線上

enotsock:

sock

索引的不是套接字

Send函式和Recv函式解析

分類 linux網路程式設計 2010 09 20 14 20 3625人閱讀收藏 舉報socket sockets 網路伺服器 unix tcp send函式和recv函式解析 1.send函式 int send socket s,const char far buf,int len,int fl...

recv函式和send函式

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

recv函式和send函式

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