簡體   English   中英

getsockopt()在非阻塞connect()+ select()流中返回EINPROGRESS

[英]getsockopt() returns EINPROGRESS in non blocking connect()+select() flow

更新

我的錯。 我得到的錯誤是ECONNREFUSED而不是EINPROGRESS。 檢查error變量后我發現它大於0,我打印errno而不是error 當然errnoEINPROGRESS因為它的值在調用connect()后沒有改變。

問題回答了。 謝謝大家。

我正在使用史蒂文斯的UNIX網絡編程非>阻塞connect()示例中的相同代碼:

  1. 將套接字設置為非阻塞
  2. 啟動非阻塞連接()
  3. 檢查立即完成
  4. 使用超時調用select()並等待讀取或寫入就緒
  5. 當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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM