recv是socket程式設計中最常用的函式之一,在阻塞狀態的recv有時候會返回不同的值,而對於錯誤值也有相應的錯誤碼,分別對應不同的狀態,下面是我針對常見的幾種網路狀態的簡單總結。
首先阻塞接收的recv有時候會返回0,這僅在對端已經關閉tcp連線時才會發生。
而當拔掉裝置網線的時候,recv並不會發生變化,仍然阻塞,如果在這個拔網線階段,socket被關掉了,後果可能就是recv永久的阻塞了。
所以一般對於阻塞的socket都會用setsockopt來設定recv超時。
當超時時間到達後,recv會返回錯誤,也就是-1,而此時的錯誤碼是eagain或者ewouldblock,posix.1-2001上允許兩個任意乙個出現都行,所以建議在判斷錯誤碼上兩個都寫上。
如果socket是被對方用linger為0的形式關掉,也就是直接發rst的方式關閉的時候,recv也會返回錯誤,錯誤碼是enoent
還有一種經常在**中常見的錯誤碼,那就是einter,意思是系統在接收的時候因為收到其他中斷訊號而被迫返回,不算socket故障,應該繼續接收。但是這種情況非常難再現,我嘗試過一邊一直在不停的發訊號,一邊用recv接收資料,也沒有出現過。這種異常錯誤我附近只有乙個朋友在用write的時候見到過一次,但是總是會有概率出現的,所以作為完善的程式必須對此錯誤進行特殊處理。
一般設定超時的阻塞recv常用的方法都如下:
while(1)
else
break;//跳出接收迴圈}}
最後,如果recv的返回值為0,那表明連線已經斷開,我們的接收操作也應該結束。
阻塞與非阻塞recv返回值沒有區分,都是 <0 出錯 =0 連線關閉 >0 接收到資料大小。
linux環境下,須如下定義:struct timeval timeout = ;
//設定傳送超時
setsockopt(socket,sol_socket,so_sndtimeo,(char *)&timeout,sizeof(struct timeval));
//設定接收超時
setsockopt(socket,sol_socket,so_rcvtimeo,(char *)&timeout,sizeof(struct timeval));
阻塞與非阻塞賦值
李秋鳳,華清遠見嵌入式學院 講師。稍微接觸過verilog hdl的都對阻塞與非阻塞賦值略知一二,也是我們經常強調的重點之一,在課堂上還是有學員問什麼不一樣呢,為什麼我用阻塞賦值也能得出正確的結果呢?在編寫可綜合 的時候,建議大家不要忘了開啟rtl網表檢視器看看我們自己綜合出來的電路是不是自己想要的...
socket connect 阻塞與非阻塞
socket函式生成socket結構體時,預設生成的socket是阻塞的 如果我們使用connect去連線伺服器,而這時網路出現故障,則connect預設等候很長一段時間然後返回錯誤 我們可以設定socket為非阻塞模式,可以設定一定的等候時間,如果在設定的等候時間內connect失敗,則我們判定網...
阻塞與非阻塞I O
還記得上篇 我們講到的是linux中併發控制訪問的手段有哪些?原子 訊號量 自旋鎖 互斥體。這是為了保護臨界區的資源,是多個程序對共享資源的併發訪問的一種處理手段。但是,在驅動程式中,我們常常為了支援使用者空間對裝置的靈活訪問,引入了阻塞與非阻塞i o兩種不同模式。阻塞操作是指在執行裝置操作時若不能...