深入理解send/recv系統調用!

來源:互聯網
上載者:User

int 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訊號,進程對該訊號的預設處理是進程終止。
通過測試發現,非同步socket的send函數在網路剛剛斷開時還能發送返回相應的位元組數,同時使用select檢測也是可寫的,但是過幾秒鐘之後,再send就會出錯了,返回-1。select也不能檢測出可寫了。

recv函數


int 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訊號,進程對該訊號的預設處理是進程終止。

本文來自ChinaUnix部落格,如果查看原文請點:
http://blog.chinaunix
.net/u3/111204/showart_2179522.html

 

 

以上部分來源於網路,關於send/recv人云亦云的個人認為還可以的概念性描述——僅作日後參考

 

一下是本人工作實踐遇到的問題及原因分析:

1,send/recv : Bad file  descriptor    ——通訊端描述符已被關閉(無效),這是一段描述“It could be that you are closing the client socket before the thread
gets a chance to run, or it could be that your thread is improperly
setup.

2,send/recv:broken sigpipe  在讀寫時候(通訊端緩衝區中並沒有資料,一直等待),如果出現網路異常,TCP/UDP協議無法將資料包傳送到目的地,或者讀寫延遲時間已到,那麼作業系統會拋給當前進程一個SIGPIPE訊號,進程的預設處理是終止進程。

3,send/recv:connect reset by peer  由於網路異常,服務端主動關閉了通訊鏈路(socket),在用戶端read之前

RST包已經傳輸到並被client socket接收緩衝區接受,那麼此時用戶端就會就會報這種錯誤

4, 以上2與3的區別:

    The
client's call to readline may happen before the server's RST is
received by the client, or it may happen after. If the readline happens
before the RST is received, as we've shown in our example, the result
is an unexpected EOF in the client. But if the RST arrives first, the
result is an ECONNRESET ("Connection reset by peer") error return from
readline.

5,服務端主動斷開socket,不一定是網路不穩定,還有可能就是用戶端一些錯誤操作導致服務端主動關閉,還有就是服務端壓力過大導致自身關閉一些socket

 

本文可以結合來看:http://blog.csdn.net/HULIHONG/archive/2011/04/26/6363202.aspx,會有更深層次的理解

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.