views:

460

answers:

4

Hi Everyone,

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

+2  A: 

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.

elder_george
elder_george,Many thanks for answering the question.But, is there any way that client connect request gets failed whenever it try to connect with tcp server.
immi
+1  A: 

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!

jdehaan
+1  A: 

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.

Len Holgate
Thanks for providing suggestions. I got ur idea. Its good and practical. I do not thing, I shall be able to go for the approach of closing the listening socket, but intend to think seriously about the 2nd approach.Just for the knowledge, i want to ask, is there any way to bring a socket in the state, it was before listening? For example, if i have bound a socket and currently listen on it, how i can cancel the listening mode on the socket without closing it.Waiting for ur reply.
immi
There's no way to do that, as far as I know. Anyway, why bother?
Len Holgate
+2  A: 

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.

Warren Young
Its a nice reply, Warren Young. Thanks for ur time and reply.
immi
Nice, I'd forgotten about that :) What does a client see if the server rejects the connection?
Len Holgate
RST at the TCP level, WSAECONNREFUSED at the Winsock level.
Warren Young
Warren Young, since ur answer suggests what i want to do, i m accepting it. Thank again to you and all who replied especially to Len Holgate who gave some really nice suggestions. My best wishes are for all of you.
immi