recv是socket編程中最經常使用的函數之一,在阻塞狀態的recv有時候會返回不一樣的值,而對於錯誤值也有相應的錯誤碼,分別對應不一樣的狀態,下面是我針對常見的幾種網絡狀態的簡單總結。
首先阻塞接收的recv有時候會返回0,這僅在socket被正常關閉時纔會發生。
而當拔掉設備網線的時候,recv並不會發生變化,仍然阻塞,若是在這個拔網線階段,socket被關掉了,後果可能就是recv永久的阻塞了。
因此通常對於阻塞的socket都會用setsockopt來設置socket的超時。
當超時時間到達後,recv會返回錯誤,也就是-1,而此時的錯誤碼是EAGAIN或者EWOULDBLOCK,POSIX.1-2001上容許兩個任意一個出現都行,因此建議在判斷錯誤碼上兩個都寫上。
若是socket是被對方用linger爲0的形式關掉,也就是直接發RST的方式關閉的時候,recv也會返回錯誤,錯誤碼是ENOENT
還 有一種常常在代碼中常見的錯誤碼,那就是EINTER,意思是系統在接收的時候由於收到其餘中斷信號而被迫返回,不算socket故障,應該繼續接收。但 是這種狀況很是難再現,我嘗試過一邊一直在不停的發信號,一邊用recv接收數據,也沒有出現過。這種異常錯誤我附近只有一個朋友在用write的時候見 到過一次,可是老是會有機率出現的,因此做爲完善的程序必須對此錯誤進行特殊處理。
通常設置超時的阻塞recv經常使用的方法都以下:
while(1)
{
cnt = (int)recv(m_socket, pBuf,RECVSIZE, 0);
if( cnt >0 )
{
//正常處理數據
}
else
{
if((cnt<0) &&(errno == EAGAIN||errno == EWOULDBLOCK||errno == EINTR))
{
continue;//繼續接收數據
}
break;//跳出接收循環
}
}編程