非阻塞模式下,雖然connect出錯,但是getsockopt取得的錯誤卻是0的問題
阿新 • • 發佈:2018-12-25
除錯專案程式碼時,發現了一個奇怪問題,記錄如下:
非阻塞模式下,connect發起建鏈,返回-1(這在非阻塞模式下是很正常的現象)。然後將該socket的寫事件進行監聽,在寫事件觸發後,getsockopt函式獲取錯誤(SO_ERROR)時,沒有檢測到發生錯誤(第四個引數返回0),最後在write操作時,發生錯誤。
原因:因配置檔案的問題,導致得到的對端IP地址為空字串"":
struct sockaddr_in saddr; saddr.sin_addr.s_addr = inet_addr(""); saddr.sin_family = AF_INET; /* "default" family */ saddr.sin_port = htons(22);
但是,在connect返回-1時,沒有檢測錯誤碼是否為EINPROGRESS:
if(connect(m_hSocket, pAddr, nAddrLen) == 0)
{
return true;
}
else
{
return false;
}
之後直接開始監聽寫事件。因為connect出錯時,該socket套接字上的寫連線已經關閉,所以寫事件立即觸發。
呼叫getsockopt時,獲取的錯誤碼為0,認為沒有錯誤。
再接下來的write操作時,write寫入一個已經關閉的連線,導致觸發SIGPIPE訊號。
總結:
雖然非阻塞模式下的connect,一般情況下都是返回-1,但是卻忘了檢測errno是否為EINPROGRESS,就像這個問題,因為地址寫錯了,connect返回-1,但是此時的錯誤卻是"Network is unreachable",這種情況下就不能再監聽該socket上的寫事件,並在回撥函式中呼叫getsockopt了,因為getsockopt得不到錯誤碼,只會返回0。