Best design pattern for a TCP "HUB" service

D

danavni

i need to build a service that will accept incoming TCP/IP connections.
the service should act like a "HUB" where on one side clients connect
to it and stay connected for as long as they like and on the other side
the service reads messages for these clients from MSMQ and sends them
to already connected clients. the clients can also send information
back to the "HUB" which will be parsed and sent to MSMQ.
when the clients connect to this service, they send their unique
identity to the server over the TCP/IP stream (the client ip is NOT
fixed so i can't use that for authentication).

i thought of 2 designs for this:
design 1:
1. have a class that listens for incoming connections (using the
TcpListener class).
2. when an incoming connection arrives, it accepts it and spawns a new
thread with the the incoming connection. the thread will receive the
incoming identity and then store itself (the thread class instance
along with the client's identity in a hashtable). then the thread
(class) will wait for more data from the client or will send data to
the client if the thread on item #3 calls a send data method.
3. have a class that periodically reads the MSMQ for messages to
clients. get the target client unique id, find the appropriate class in
the hash table and call the send data method for the specific class
(which in theory should still hold the connection open).

design 2:
1. have a class that listens for incoming connections (using the
TcpListener class).
2. when an incoming connection arrives, it accepts it and spawns a new
thread that will just read the unique id and add to the hashtable the
connection and the unique id as the key. this thread is then destroyed.
3. have another thread that will scan the hashtable all the time and
look for incoming data, read it and parse it.
4. have a thread than reads MSMQ for messages to the clients, pulls the
correct connection from the hashtable and send the message to the
client.

both designs should work but i would like to hear ideas and/or comments
about the designs.

what is the maximal number of threads i can spawn? max number of TCP/IP
clients the service can support?

i need a design that will be able to support as many clients as
possible but on the same time not be too demanding on server resources.

thanks
 
P

Peter Huang [MSFT]

Hi

According to the MSDN below,

The number of threads a process can create is limited by the available
virtual memory. By default, every thread has one megabyte of stack space.
Therefore, you can create at most 2028 threads. If you reduce the default
stack size, you can create more threads. However, your application will
have better performance if you create one thread per processor and build
queues of requests for which the application maintains the context
information. A thread would process all requests in a queue before
processing requests in the next queue.

CreateThread
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/bas
e/createthread.asp

For the maximum socket a TCPLister can accept, in theory it is 2^32-1, we
can consider it as unlimited, because every time we create a socket, the
system will allocate kernel memory for the socket handle, so the accutal
account is hard to determine, because the other program will also use the
handle(e.g. file handle, gdi hanle ...) which will share the system kernel
memory.

In Socket programming, we have another term named backlog, which means the
connection request queue length before we accept it.

Use the Start method to begin listening for incoming connection requests.
Start will queue incoming connections until you either call the Stop method
or it has queued MaxConnections. Use either AcceptSocket or AcceptTcpClient
to pull a connection from the incoming connection request queue. These two
methods will block. If you want to avoid blocking, you can use the Pending
method first to determine if connection requests are available in the queue.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/
frlrfsystemnetsocketstcplistenerclasstopic.asp

Backlog Parameter
Windows Sockets server applications generally create a socket and then use
the listen() function on the socket to receive connection requests. One of
the parameters passed when using the listen() function is the backlog of
connection requests that the application would like Windows Sockets to
queue for the socket. The Windows Sockets 1.1 specification indicates that
the maximum allowable value for backlog is 5; however, Microsoft? Windows
NT? version 3.51 accepts a backlog of up to 100, Microsoft? Windows NT? 4.0
Server and Windows 2000 Server accepts a backlog of 200, and Microsoft?
Windows NT? 4.0 Workstation and Windows 2000 Professional accepts a backlog
of 5 (which reduces the memory footprint).

The backlog is usually used to consider the concurrent TCP connection
request.

Since newsgroup support did not provide advisory service, I just give some
general idea based on my knowlege.
If the maximum clients is not large, e.g. 100, you may try to use the first
design, because that is easy to implement, every client will have a
specified thread to do that.

While if the maximum client will be 1000 and more, according to the thread
count limitation, the second one will be OK. As a suggestion, if you want
to increase the performance, you may create more than one thread to query
the hashtable to handle the connection.

Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
 
D

danavni

Hi Peter,

thank you very much for the overview and recommendations! since the
client will try to connect if his connection request fails then the
backlog is not too much of a concern altough i would like to accept all
incoming connections all the time.
based on your recommendations i think i would go with option 2 wich
will take a bit more writing but will support a large amout of clients
(if i get to a large enough number then i am rich and can buy another
server for clients to connect :)

again thanks for all your help!
Dan Avni
 
P

Peter Huang [MSFT]

Hi Dan,

I am glad that my suggestion helped you.
If you still have any concern, please feel free to post here! :)


Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top