我想从TCP服务器一次只允许一个连接。你能告诉我,如何使用没有积压长度为零的听力。
我正在使用代码(如下所示),但是当我逐个启动2个客户端时,两者都会连接起来。我使用VC ++和winsock2。
听(m_socket,-1);
传递零作为积压也不起作用。
等待你的回复。
的问候,
IMMI
答案 0 :(得分:6)
如果您确实可以将应用程序限制为仅使用Winsock 2,则可以使用其条件接受机制:
SOCKET sd = socket(...);
listen(sd, ...);
DWORD nTrue = 1;
setsockopt(sd, SOL_SOCKET, SO_CONDITIONAL_ACCEPT, (char*)&nTrue, sizeof(nTrue));
只要连接积压空间可用,这就会将堆栈的行为更改为不会自动向传入的SYN数据包发送SYN-ACK个回复。相反,你的程序得到它应该接受正常连接的信号 - select(),WSAEventSelect(),WSAAsyncSelect()... - 然后你调用WSAAccept()而不是accept():
sockaddr_in sin;
WSAAccept(sd, (sockaddr*)&sin, sizeof(sin), ConditionalAcceptChecker, 0);
您编写函数ConditionalAcceptChecker()以查看传入的连接信息并决定是否接受连接。在您的情况下,只要您已经处理了连接,就可以返回CF_REJECT
。
再次注意,这种机制特定于Winsock 2.如果你需要可移植的行为,那么在你的程序已经连接时,其他帖子建议关闭监听套接字会更好。
答案 1 :(得分:2)
您可以将backlog设置为1,因为这是您想要的连接数。
但AFAIK对队列大小没有严格的保证(this doc表示在BSD上会有1.5 *的积压,例如。)
恕我直言,你可以通过在一些限制之后不接受()连接来手动控制连接数。
答案 2 :(得分:1)
我想说,只有accept
一次。如果您在服务器上一次只需要一个客户端,则也可以只使用一个线程来执行处理。积压仅限制系统处理的待处理连接数量(在第一次接受后队列再次为空,以便下一个客户端进入待办事项)而不是连接数量!
答案 3 :(得分:1)
这不是听力积压的用途。
侦听backlog会影响用于挂起连接的队列,它允许TCP堆栈将挂起的连接排队等待您接受。
要执行您想要执行的操作,您需要接受您允许的一个连接,然后关闭侦听套接字。完成单个客户端后,您可以重新创建侦听套接字并侦听新连接。这将阻止多个客户端连接到您,但客户端无法知道您实际上正在运行并接受“一次一个”的连接。除了设法连接的客户之外的所有客户都认为你不在那里。
保持监听套接字打开并接受所有连接可能是一个更好的设计,但是一旦你拥有“一个”活动连接,你只需接受然后向你的客户发送一个应用程序级别的消息,告诉它你不能再接受了连接或如果您不能这样做,只需关闭新连接即可。