[英]getsockopt() returns EINPROGRESS in non blocking connect()+select() flow
更新 :
我的錯。 我得到的錯誤是ECONNREFUSED而不是EINPROGRESS。 檢查error
變量后我發現它大於0,我打印errno
而不是error
。 當然errno
是EINPROGRESS
因為它的值在調用connect()
后沒有改變。
問題回答了。 謝謝大家。
我正在使用史蒂文斯的UNIX網絡編程非>阻塞connect()示例中的相同代碼:
- 將套接字設置為非阻塞
- 啟動非阻塞連接()
- 檢查立即完成
- 使用超時調用select()並等待讀取或寫入就緒
- 當select()返回值大於0時,執行getsockopt(socket,SOL_SOCKET,SO_ERROR,&error,&len)。
我得到的錯誤是EINPROGRESS。 代碼在rhel5服務器上執行。
任何想法為什么我收到此錯誤?
代碼段 :
flags = fcntl(sockfd, F_GETFL, 0);
fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
if ((retVal = connect(sockfd, saptr, salen)) < 0)
if (errno != EINPROGRESS)
return (-1);
if (retVal == 0)
{
// restore file status flags
fcntl(sockfd, F_SETFL, flags);
return 0;
}
FD_ZERO(&rset);
FD_SET(sockfd, &rset);
wset = rset;
tval.tv_sec = nsec;
tval.tv_usec = 0;
if ((retVal = select(sockfd + 1, &rset, &wset, NULL, &tval)) == 0)
{
// timeout
close(sockfd);
errno = ETIMEDOUT;
return (-1);
}
if (retVal < 0)
{
// select() failed
return (-1);
}
if (FD_ISSET(sockfd, &rset) || FD_ISSET(sockfd, &wset))
{
len = sizeof(error);
error = 0;
if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len) < 0)
return (-1);
if (error > 0) //<<<<< error == EINPROGRESS >>>
{
close(sockfd);
errno = error;
return (-1);
}
}
else
{
return (-1);
}
// restore file status flags
fcntl(sockfd, F_SETFL, flags);
糟透了......我放棄了。 我嘗試過但嘗試過但找不到代碼問題。 所以,我提供的只是一些建議和假設。
使用FD_COPY將rset復制到wset。
當第一次連接失敗時,你能做一個getsockopt嗎? 我懷疑Select返回0並且由於上面的原因,你的writefd集被設置並且做一個getsockopt正在返回你之前連接的陳舊錯誤。 IMO,一個后續連接應返回EALREADY(盡管它可能與平台有關)
請執行以上操作(如果我錯誤地使用FD_COPY,請向我投票)並分享結果
大於零的選擇值不表示任何類型的錯誤...它是符合select語句條件的套接字數。 如果發生故障,select將返回-1。
當使用SO_ERROR調用getsocktopt時,我不清楚它是否有效; 每次使用套接字時,你最好堅持檢查錯誤(我認為你正在做的事情)。 選擇沒有失敗,你很好。
EINPROGRESS表示非阻塞connect()仍在進行中。
所以我會問 - 你在select()返回后檢查是否仍然在writefds fd_set中設置了connect()文件描述符? 如果不是,那么這意味着select()已經返回了其他原因。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.