connect(),accept()和select()发生序列顺序

我是C的新手.我刚注意到只要TCP三向握手完成,客户端的connect()函数就可以返回.我的意思是connect()甚至可以在调用服务器端的accept()之前返回(如果我错了,请纠正我).基于这些知识,我的问题是,当我在客户端调用select()并观察文件描述符以等待它可写时,当select()成功返回时,这意味着服务器端已经调用了accept ()现在我可以安全地写到服务器端,对吗?非常感谢你的时间.

int flags = fcntl(fd, F_GETFL);

flags |= O_NONBLOCK;

fcntl(fd, F_SETFL, flags);

if (connect(fd, (struct sockaddr *)saptr, salen) < 0)
{
    if (errno != EINPROGRESS)
        /* error_return */
}

fd_set set;
FD_ZERO (&set);

FD_SET (fd, &set);

select (FD_SETSIZE, NULL, &set, NULL, &timeout)
/* Here, if select returns 1, that means accept() is already called 
   on the server side, and now I can safely write to the server, right? */

最佳答案

when select() successfully returns, that means the server side has already called accept()

不,不一定. connect()在连接尝试完成时返回,成功或失败.在远程端,这由网络堆栈处理,在任何应用程序的上下文之外.后续的accept()本身不会产生额外的通信.

and now I can safely write to the server side, right?

你可以通过“安全”来表达各种各样的东西,但是如果你的意思是本地方可以写入至少一个字节而不阻塞那么是,select()承诺你.无论你成功写什么,都会通过电线发送到远程端.它可以在那里缓冲一段时间,具体取决于远程端软件的行为.该软件是否已接受()连接与该问题没有直接关系.

更新:还要注意网络堆栈维护已建立连接的每个套接字队列,这些连接尚未被接受()ed(其积压).这种排队行为是服务器在建立后立即不接受()连接的一个原因,特别是在负载很重的情况下.

点赞