2011-06-01 61 views
9

我想設置的功能超時值連接,但我得到這個錯誤:「操作正在進行」操作現在在連接(函數)進度的錯誤錯誤

我的代碼:

if ((he = gethostbyname(authdefhost)) == NULL) { 
     snprintf(errbuf, CERRBUFSIZ - 1, "cannot resolve %s: %s\n", authdefhost, hstrerror(h_errno)); 
     return -1; 
} 

sin.sin_family = AF_INET; 
memcpy(&sin.sin_addr, he->h_addr_list[0], sizeof(struct in_addr));  

if ((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { 
     snprintf(errbuf, CERRBUFSIZ - 1, "cannot create client socket: %s\n", strerror(errno)); 
     return -1; 
} 

if ((fcntl(sd, F_SETFL, O_NONBLOCK) < 0)) 
    printf("error on setting socket flags."); 

if (connect(sd, (void *) & sin, sizeof(sin)) == -1) { 
     snprintf(errbuf, CERRBUFSIZ - 1, "cannot connect to server %s: %s\n", authdefhost, strerror(errno)); 
     close(sd); 
     return -1; 
} 

FD_ZERO(&fdset); 
FD_SET(sd, &fdset); 
int rv; 
if ((rv = select(sd + 1, NULL, &fdset, NULL, &tv)) == -1) { 
    printf("error occurred on select function."); 
    return -1; 
} 
else if (rv == 0) { 
    printf("time out occurred."); 
    return -1; 
} 
else { 
    printf("connection established"); 
    return sd; 
} 

回答

24

當您在非阻塞套接字上調用connect(),您將獲得EINPROGRESS而不是阻止等待連接握手完成。然後,您必須爲select()提供可寫性,並檢查套接字錯誤以查看連接是否已完成。

從Linux的connect() manpage

EINPROGRESS 

    The socket is nonblocking and the connection cannot be completed 
    immediately. It is possible to select(2) or poll(2) for completion by 
    selecting the socket for writing. After select(2) indicates 
    writability, use getsockopt(2) to read the SO_ERROR option at level 
    SOL_SOCKET to determine whether connect() completed successfully 
    (SO_ERROR is zero) or unsuccessfully (SO_ERROR is one of the usual 
    error codes listed here, explaining the reason for the failure). 

+6

簡而言之:這是預期。你需要在'connect()'的錯誤檢查路徑中檢查'errno!= EINPROGRESS'。 – caf 2011-06-02 06:21:16

+1

*第16章** UNIX網絡編程(第1卷)的非阻塞I/O * **詳細描述此功能並提供演示。 – diabloneo 2014-02-23 09:08:34