正确设置了非阻塞套接字后,我将进行以下连接:
errno
不是EINPROGRESS
,则出现错误。如果errno
为EINPROGRESS
,我可以通过以下方式轮询连接状态:
select_status = sock_select(FD_SETSIZE, NULL, &file_descriptor_set, NULL, &timeout);
如果select_status > 0
,然后用FD_ISSET
检查是否设置了文件描述符。
正确吗?我应该检查fd_write
而不是fd_read
吗?选择后我应该打电话给getsockopt
吗?有什么论点?
我找不到需要做什么的清晰说明。
我确实连接了,但是我的程序没有正确报告它,所以我使用select
错误,或者是因为我没有检查getsockopt
。
什么告诉我建立了连接?
- 调用套接字上的连接。
- 如果返回0,则表明我已经连接,否则返回errno。
- 如果errno不是EINPROGRESS,则出现错误。
以上所有方法都是正确的(Windows下除外,您需要检查WSAEWOULDBLOCK而不是EINPROGRESS)。
- 如果errno是EINPROGRESS,我可以通过以下方式轮询连接状态:select_status = sock_select(FD_SETSIZE,NULL,&file_descriptor_set,NULL,&timeout);如果select_status> 0,则检查FD_ISSET是否设置了文件描述符。
正确(假设sock_select()与select()是相同的东西,除了FD_SETSIZE应该是您正在观看的所有文件描述符值的最大值加上1。
正确吗?我应该检查fd_write而不是fd_read吗?
正确。
什么告诉我建立了连接?
当异步连接操作完成后,select()将返回,并且FD_ISSET(theSocket,&writeSet)将返回true。
发生这种情况时,您需要确定连接尝试是成功还是失败。这是我为此使用的功能:
// Returns true if the async connection on (fd) is connected; false if it failed
bool DidTheAsyncTCPConnectionSucceed(int fd)
{
struct sockaddr_in junk;
socklen_t length = sizeof(junk);
memset(&junk, 0, sizeof(junk));
return (getpeername(fd, (struct sockaddr *)&junk, &length) == 0);
}
如果返回true,则说明您的套接字已连接并可以正常使用。如果返回false,则表明异步连接失败,您应该关闭套接字并以某种方式处理该失败。
(再次在Windows下有稍微不同的行为;在Windows下,如上所述,可以成功获得有关连接成功的通知,但是,如果您想获得有关连接失败的通知,则需要观看exception-fd-在Windows中,当异步TCP连接失败时,FD_ISSET(fd,&exceptionSet)会通知您)。