2011-06-01 33 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