Socket send函式和recv函式詳解

2021-07-26 06:05:01 字數 2716 閱讀 6888

1.send 函式 i

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

不論是客戶還是伺服器應用程式都用send函式來向tcp連線的另一端傳送資料。

客戶程式一般用send函式向伺服器傳送請求,而伺服器則通常用send函式來向客戶程式傳送應答。

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

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

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

第四個引數一般置0。 

這裡只描述同步socket的send函式的執行流程。當呼叫該函式時,

(1)send先比較待傳送資料的長度len和套接字s的

傳送緩衝的長度

, 如果len大於s的傳送緩衝區的長度,該函式返回socket_error;

(2)如果len小於或者等於s的傳送緩衝區的長度,那麼send先檢查協議是否正在傳送s的傳送緩衝中的資料,如果是就等待協議把資料傳送完,如果協議還沒有開始傳送s的傳送緩衝中的資料或者s的傳送緩衝中沒有資料,那麼send就比較s的傳送緩衝區的剩餘空間和len

(3)如果len大於剩餘空間大小,send就一直等待協議把s的傳送緩衝中的資料傳送完

(4)如果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訊號,程序對該訊號的預設處理是程序終止。

非同步socket的send函式在網路剛剛斷開時還能傳送返回相應的位元組數,同時使用select檢測也是可寫的,但是過幾秒鐘之後,再send就會出錯了,返回-1。select也不能檢測出可寫了。

2.recv函式

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

不論是客戶還是伺服器應用程式都用recv函式從tcp連線的另一端接收資料。

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

第二個引數指明乙個緩衝區,該緩衝區用來存放recv函式接收到的資料; 

第三個引數指明buf的長度; 第四個引數一般置0。

這裡只描述同步socket的recv函式的執行流程。當應用程式呼叫recv函式時,

(1)recv先等待s的傳送緩衝中的資料被協議傳送完畢,如果協議在傳送s的傳送緩衝中的資料時出現網路錯誤,那麼recv函式返回socket_error,

(2)如果s的傳送緩衝中沒有資料或者資料被協議成功傳送完畢後,recv先檢查套接字s的接收緩衝區,

如果s接收緩衝區中沒有資料或者協議正在接收數 據,那麼recv就一直等待,直到協議把資料接收完畢。

當協議把資料接收完畢,recv函式就把s的接收緩衝中的資料copy到buf中

(注意協議接收到的資料可能大於buf的長度,所以 在這種情況下要呼叫幾次recv函式才能把s的接收緩衝中的資料copy完。

recv函式僅僅是copy資料,真正的接收資料是協議來完成的), recv函式返回其實際copy的位元組數。

如果recv在copy時出錯,那麼它返回socket_error;

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

預設 socket 是阻塞的 解阻塞與非阻塞recv返回值沒有區分,都是<0 出錯 =0 連線關閉 >0 接收到資料大小

特別:返回值<0時並且(errno == eintr || errno == ewouldblock || errno == eagain)的情況下認為連線是正常的,繼續接收。

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

返回說明: 

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

另一端已關閉則返回0。

失敗返回-1,

errno被設為以下的某個值 

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

ebadf:sock不是有效的描述詞 

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

efault:記憶體空間訪問出錯 

eintr:操作被訊號中斷 

einval:引數無效 

enomem:記憶體不足 

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

enotsock:sock索引的不是套接字 當返回值是0時,為正常關閉連線;

思考:當對側沒有send,即本側的套接字s的接收緩衝區無資料,返回值是什麼(eagain,原因為超時,待測)

Socket send函式和recv函式

不論是客戶還是伺服器應用程式都用send函式來向tcp連線的另一端傳送資料。客戶程式一般用send函式向伺服器傳送請求,而伺服器則通常用send函式來向客戶程式傳送應答。該函式的第乙個引數指定傳送端套接字描述符 第二個引數指明乙個存放應用程式要傳送資料的緩衝區 第三個引數指明實際要傳送的資料的位元組...

Socket send函式和recv函式

send 函式 int send socket s,const char far buf,int len,int flags 不論是客戶還是伺服器應用程式都用send函式來向tcp連線的另一端傳送資料。客戶程式一般用send函式向伺服器傳送請求,而伺服器則通常用send函式來向客戶程式傳送應答。該函...

Socket send函式和recv函式詳解zz

1.send 函式 i nt send socket s,const char far buf,int len,int flags 不論是客戶還是伺服器應用程式都用send函式來向tcp連線的另一端傳送資料。客戶程式一般用send函式向伺服器傳送請求,而伺服器則通常用send函式來向客戶程式傳送應答...