简体   繁体   中英

Winsock2: How to allow ONLY one client connection at a time by using listen's backlog in VC++

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

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.

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, eg).

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

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!

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM