3

Hopefully two simple questions relating to creating a server application:

  • Is there a theoretical/practical limit on the number of simultaneous sockets that can be open? Ignoring the resources required to process the data once it has arrived! If its of relevance I am targeting the .net framework
  • Should each connection be run in a separate thread that's permanently assigned to it, or should use of a Thread Pool be made? The dedicated thread approach seems simpler, but it seems odd to have 100+ threads running it once. Is this acceptable practice?

Any advice is greatly appreciated Venatu

Venatu
  • 1,264
  • 1
  • 13
  • 24
  • 1
    Assuming you want multiple people to be able to connect at once, then you will need at least one thread per connection. – Jordan Jul 09 '11 at 21:41
  • Could you not cycle through the sockets in turn, on a limited number of threads, with one dedicated to accepting incoming requests? – Venatu Jul 09 '11 at 21:44
  • That is a possibility, but you definitely run the risk of having a very long queue if you have long running connections. When I say "thread", I really mean "method of asynchronously receiving and sending data", so ThreadPooling or async sockets would work too. – Jordan Jul 10 '11 at 21:55

3 Answers3

2

There are practical limits, yes. However, you will most likely run out of resources to handle the load long before you reach them. CPU, or memory are more likely to be exhausted before number of connections.

For maximum scalability, you don't want a seperate thread per connection, but rather you would use an Asynchronous model that only uses threads when servicing active (as in receiving or sending data) connections.

Erik Funkenbusch
  • 92,674
  • 28
  • 195
  • 291
2

You may find the following answer useful. It illustrates how to write a scalable TCP server using the .NET thread pool and asynchronous sockets methods (BeginAccept/EndAccept and BeginReceive/EndReceive).

This being said it is rarely a good idea to write its own server when you could use one of the numerous WCF bindings (or even write custom ones) and benefit from the full power of the WCF infrastructure. It will probably scale better than every custom written server.

Community
  • 1
  • 1
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • Thanks that provided a pattern similair to what I had in mind, as I was already using begin/end accept. That solved me need perfectly! While I appreciate the mention of wcf, unfortunately only the server is .net. The client is an android app, meaning bandwidth is tight. Also, the connection is always on (its a simple multiplayer game) where wcf is http/soap based? While I love the simplicity of wcf compared to raw sockets, in this case I dont think I have a choice. Hopefully I dont have wrong assumptions about wcf! – Venatu Jul 09 '11 at 22:05
  • 1
    @Venatu, no you are doing wrong assumptions about WCF. It's not limited to HTTP/SOAP based. You could use binary bindings over TCP. They might be not very interoperable but you could write your custom bindings if you will and use any protocol. It's very customizable and that's the power of it. Also you could use REST or POX over HTTP which could be more optimized than SOAP. So if I had one advice towards you is this: USE WCF if you intend to host a server on the .NET platform. – Darin Dimitrov Jul 09 '11 at 22:08
  • My other concern with the bandwidth was HTTP headers (exacerbated by many small messages), but if Http is avoidable, thats not an issue. Id be a fool to ignore good advice! Thanks for correcting me, Ill look into it. – Venatu Jul 09 '11 at 22:11
  • I find WCF does not work well for long running TCP connections. It runs into various arbitrary messae length issues, and is generally a pain in the rear. You get weird timeouts, and then it won't reconnect after a certain number of connnections (even after changing the default limit). It's like some internal resource gets exausted and you have to restart. – Erik Funkenbusch Jul 09 '11 at 23:10
1

As I remember correctly (did sockets long time ago) the very best way of implementing them is with ReceiveAsync (.NET 3.5) / BeginReceive methods using asynchronous callbacks which will utilize thread pool. Don't open a thread for every connection, it is a waste of resources.

Denis Biondic
  • 7,943
  • 5
  • 48
  • 79