3

我想一次只允许来自我的 TCP 服务器的一个连接。你能告诉我,如何在没有积压长度为零的情况下使用监听。

我正在使用代码(如下所示),但是当我一个一个启动 2 个客户端时,两个客户端都已连接。我正在使用带有winsock2的VC++。

听(m_socket,-1);

将零作为积压传递也不起作用。

等待你的回复。

问候,
伊米

4

4 回答 4

7

如果你确实可以限制你的应用程序只使用 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 的。如果您需要可移植的行为,其他帖子的建议是在您的程序已经建立连接时关闭侦听套接字会更好。

于 2009-10-15T12:42:21.017 回答
2

您可以将 backlog 设置为 1,因为这是您想要的连接数。

但是 AFAIK 对队列大小没有硬性保证(该文档说它将是 BSD 上的 1.5 * 积压,例如)。

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

于 2009-10-15T08:08:46.960 回答
2

这不是监听积压的目的。

侦听积压影响用于挂起连接的队列,它允许 TCP 堆栈将挂起的连接排队等待您接受。

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

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

于 2009-10-15T11:02:20.367 回答
2

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

于 2009-10-15T08:29:33.760 回答