Winsock2:如何通过使用 VC 中的监听积压,一次只允许一个客户端连接

发布于 2024-08-07 15:30:36 字数 211 浏览 10 评论 0原文

我想一次只允许来自我的 TCP 服务器的一个连接。您能告诉我如何使用listen而不积压长度为零吗?

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

听(m_socket,-1);

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

等待你的回复。

问候,
伊米

I want to allow only one connection at a time from my TCP server. Can you please tell, how to use listen without backlog length of zero.

I m using the code(given below), but when i launch 2 client one by one, both gets connected. I m using VC++ with winsock2.

listen(m_socket,-1);

passing zero as backlog is also not working.

Waiting for ur reply.

Regards,
immi

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

云仙小弟 2024-08-14 15:30:36

如果您确实可以限制您的应用程序仅使用 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() 而不是 Accept():

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

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

再次注意,此机制特定于 Winsock 2。如果您需要可移植行为,其他帖子建议在您的程序已经具有连接时关闭侦听套接字,效果更好。

If you can indeed limit your application to only use Winsock 2, you can use its conditional accept mechanism:

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

This changes the stack's behavior to not automatically send SYN-ACK replies to incoming SYN packets as long as connection backlog space is available. Instead, your program gets the signal that it should accept the connection as normal -- select(), WSAEventSelect(), WSAAsyncSelect()... -- then you call WSAAccept() instead of accept():

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

You write the function ConditionalAcceptChecker() to look at the incoming connection info and decide whether to accept the connection. In your case, you can just return CF_REJECT as long as you're already processing a connection.

Again, beware that this mechanism is specific to Winsock 2. If you need portable behavior, the other posts' advice to close the listening socket while your program already has a connection is better.

你如我软肋 2024-08-14 15:30:36

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

但据我所知,对队列大小没有硬性保证(此文档 表示 BSD 上的积压量为 1.5 *,例如)。

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

You may set backlog equal to 1, since this is number of connections you want.

But AFAIK there's no hard warranty on queue size (this doc says it would be 1.5 * backlog on BSD, e.g.).

IMHO, you'd better control number of connections manually by not accept()'ing connections after some limit.

执手闯天涯 2024-08-14 15:30:36

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

I would say, only accept once. If you only want one client at a time on your server you can use also only one thread to perform the handling. The backlog limits only the amount of pending connections handled by the system for accepting (the queue is empty again after the first accept so the next client gets into the backlog) not the amount of connections!

动听の歌 2024-08-14 15:30:36

这不是监听积压的目的。

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

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

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

That's not what the listen backlog is for.

The listen backlog affects a queue that's used for pending connections, it allows the TCP stack to queue up pending connections for you to accept.

To do what you want to do you need to accept the one connection that you're allowing and then close the listening socket. Once you've finished with your single client you can recreate your listening socket and listen for a new connection. This will prevent more than a single client connecting to you but there will be no way for the client to know that you're actually running and accepting connections on a "one at a time" basis. All clients except the one that manages to connect will think you're just not there.

It's probably a better design to keep your listening socket open and accept all connections but once you have you "one" active connection you simply accept and then either send an application level message to your client telling it that you cant accept any more connections OR if you can't do that, simply close the new connection.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文