Winsock2:如何一次只允许一个客户端连接使用VC++中的listen积压

问题描述:

我想只允许从我的TCP服务器连接一个连接。你可以告诉,如何使用没有积压零长度的听。Winsock2:如何一次只允许一个客户端连接使用VC++中的listen积压

我使用代码(下面给出),但是当我一个一个地启动2个客户端时,两者都获得连接。我使用VC++与winsock2。 (m_socket,-1);

listen(m_socket,-1);

传递零作为积压也没有工作。

等待你的回复。

问候,
IMMI

如果你确实可以限制你的应用程序只使用Winsock的2,你可以使用它的条件接受机制:

SOCKET sd = socket(...); 
listen(sd, ...); 
DWORD nTrue = 1; 
setsockopt(sd, SOL_SOCKET, SO_CONDITIONAL_ACCEPT, (char*)&nTrue, sizeof(nTrue)); 

这只要改变栈的行为不是自动发送SYN-ACK回复收到的SYN数据包,连接积压空间可用。相反,你的程序得到它应该接受连接的信号 - select(),WSAEventSelect(),WSAAsyncSelect()... - 然后调用WSAAccept(),而不是接受():

sockaddr_in sin; 
WSAAccept(sd, (sockaddr*)&sin, sizeof(sin), ConditionalAcceptChecker, 0); 

你写的函数ConditionalAcceptChecker()来看看传入的连接信息,并决定是否接受该连接。就你而言,只要你已经在处理连接,你就可以返回CF_REJECT

再次,要小心,这种机制是特定对Winsock 2如果您需要携带的行为,其他职位的意见,关闭监听套接字,而你的程序已经有一个连接是更好的。

+0

这是一个很好的回复,沃伦杨。感谢您的时间和回复。 – immi 2009-10-15 13:22:23

+0

不错,我忘记了:)客户端看到服务器是否拒绝连接? – 2009-10-15 13:27:24

+0

RST在TCP级别,WSAECONNREFUSED在Winsock级别。 – 2009-10-15 16:08:35

你可以设置积压等于1,因为这是你想要连接的数量。

但AFAIK没有严格的保证队列大小(this doc表示它会在BSD 1.5 *积压,例如)。

恕我直言,你最好通过在某些限制后不接受()连接来手动控制连接数。

+0

elder_george, 非常感谢回答这个问题。 但是,有没有什么办法,客户端连接请求失败,只要它尝试连接到TCP服务器。 – immi 2009-10-15 08:20:49

我会说,只有accept一次。如果您只需要一台服务器上的一个客户端,那么您也可以只使用一个线程来执行处理。待办事项仅限制系统为接受而处理的未决连接数量(第一次接受后队列再次为空,以便下一个客户端进入待办事项)而不是连接数量!

这不是听力积压的原因。

侦听待办事项会影响用于未决连接的队列,它允许TCP堆栈排队等待连接以供您接受。

要做你想做的事情,你需要接受你允许的一个连接,然后关闭监听套接字。完成单个客户端后,您可以重新创建侦听套接字并侦听新连接。这样可以防止多个客户端连接到您,但客户端无法知道您实际上正在运行并且以“一次一个”的方式接受连接。除了管理连接的客户端之外,所有客户端都会认为你不在那里。

这可能是一个更好的设计,可以让您的监听套接字打开并接受所有连接,但是一旦您拥有了“一个”活动连接,您就可以简单接受,然后向您的客户端发送应用程序级别的消息,告诉它您不能接受更多的连接或者如果你不能这样做,只需关闭新的连接。

+0

感谢您提供建议。我有你的想法。它好而实用。 我不是这样,我可以去关闭监听套接字的方法,但打算仔细考虑第二种方法。 只是为了知识,我想问一下,有没有什么办法可以在插入状态,它是在听之前呢? 例如,如果我绑定了一个套接字并且正在侦听它,我如何取消套接字上的侦听模式而不关闭它。 等待你的回复。 – immi 2009-10-15 11:34:43

+0

就我所知,没有办法做到这一点。无论如何,为什么要麻烦? – 2009-10-15 13:28:01