Connection Limits to a Server?

Started by
3 comments, last by FreeBird 17 years, 6 months ago
Hi all, my first post here. Forgive me if its been answered, before. I've read FAQ's and generally searched web for the answer. In the end google leads me here in my searches, which was great as I love this forum already. Ramble over. Right, I have developed a matchmaking service of my own. Its been used for a few games so far (commercial ones), and its great. It works perfect, 100% reliable, 24hrs uptime of the backend server etc. When a game client connects to the matchmaker server (using a TCP socket) the code in the server that accepts it is...

void CServerSocket::OnAccept(int nErrorCode)
{
  CServerSocket *pNewSocket = new CServerSocket(m_pParent, m_nPort);
  if (Accept(*pNewSocket, NULL, 0))
  {
    m_pParent->OnConnect(pNewSocket);
  }
}
Where CServerSocket is an MFC class derived from CAsyncSocket. So the server is always listening on the same TCP port for incoming connections, and when clients connect the server copies the socket to a new object, and keeps listening on the original port. Meaning that there could be 100's or even 1000's of clients connnected to the matchmaker, all connected to the same server port. My question. Is there a limit? So far I've had about 3000 simultaneous connections to the matchmaker, but if the user base expands to 10's or 100's of thousands of simultaneous connection will problems start to arise? And if so what will happen? The call to Accept() will fail?
Advertisement
Edit: Argh. I hate it when I realize my argument didn't make sense about two seconds after I hit the "Submit" button. Since TCP uses client ip/port duples to route incoming packets, all those clients CAN be bound to the same server port. So, if the resources your server allocates per client are very light, what ends up limiting you might be the memory allocated for the TCP buffers to support each connection, which means you can probably scale up fine at least into the tens of thousands of users (I think bittorrent trackers sustain these numbers without difficulty).

--original post--
I believe that when you Accept an inbound TCP connection, a new port is allocated for the newly created socket; if all those new sockets used the same port number, TCP wouldn't know which socket to send incoming packets to. I bet if you do a 'netstat -a' on the command-line of your server, you'll see a ton of different ports bound to established TCP connections. That means you couldn't have more than 64,000 or so client connections at once.
-david
Thanks for the info Muse. I was about to argue about the port allocation but then saw your edit before I replied. 10's of thousands I not worried about really as if it will do 3000 I see no reason why 10 or 20K would be a problem. Its the 100'000s+ I am concerned about, (and by then it will be a serious system to have to take down if a huge redesign was required).

Is there some other limiting factor? Someone might know of. One of my thoughts is regarding CAsyncSocket and the way it deals with socket allocation. Doesnt it allocate a background window or something for each socket and then would that not cause a HANDLE resource shortage? I thought mabey windows would fail to create things it needed to as it was running out of resources, but still has loads of standard memory spare.

There's a CAsyncSocketEx class on www.codeproject.com I've had a go at using to replace the standard MFC CAsyncSocket. From what I can tell the fundamental difference internally is that the non-MFC version uses a single window instance for all sockets and some stl vectors and arrays etc to control multiple sockets. The reason the author did this was for speed, but presumably IF there is a HANDLE shortage at these exetems in the MFC version, this could be ideal.

CAsyncSocketEx almost worked out of the box but I had to make a few changes to get it to work EXACTLY like the MFC version in. However I dont fully trust it as I didnt write from scratch myself and it hasnt had the real world testing CAsyncSocket has in my previous server.

If its a fact that there is no TCP/IP restriction on the number of simultaneous connects to a single port (havent found one in all my searches), then I'm only worried about the MFC/WinSock implementation now.

I can't write a test program to connect 500,000 sockets to a server as that would require 500,000 unique client ports (ie about 10 PC's which I dont have at my disposal atm I have 5 though I guess so I could run a server and 4 clients using 60000 connects each for 250,000 logins). I suppose I'll have to try something along these lines if I cant get a definite answer. In fact, typing this has convinced me to try it. Cheers :)

There's services like GameSpy and XBoxLive that obviously allow for hundreds of thousands, and even millions of connections at the same time, do they use multiple central matchmaking servers or a single global one?
Do async sockets in MFC use the windows message notification mechanism (WSAAsyncSelect, etc), or are they based on I/O completion ports? If the former, then Windows itself might get in the way, because WSAAsyncSelect() just isn't that efficient. If it's based on I/O completion ports, then it'll probably scale fine until you run out of memory and CPU. Pay attention to memory allocated by, and time spent in, the kernel/drivers, when profiling this system!
enum Bool { True, False, FileNotFound };
Yes, both CAsync and its non-MFC replacement both use WSAAsyncSelect.

Until you've brought it up here, ive always though that WSAAsyncSelect was the only way to receive socket data in WinSock. The mention of "completion ports" has opened up a whole new world for me to study.

Just come across this article :-

http://msdn.microsoft.com/msdnmag/issues/1000/Winsock/

A very old one, but exactly what I need (and also a whole new thing to start googling on)

Info very much appreciated. Thanks guys.

[Edited by - FreeBird on October 22, 2006 5:28:13 AM]

This topic is closed to new replies.

Advertisement