1. 程式人生 > >非阻塞模式下,雖然connect出錯,但是getsockopt取得的錯誤卻是0的問題

非阻塞模式下,雖然connect出錯,但是getsockopt取得的錯誤卻是0的問題

    除錯專案程式碼時,發現了一個奇怪問題,記錄如下:

    非阻塞模式下,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