tags:

views:

69

answers:

2

The requirement of the TCP server:

  1. receive from each client and send result back to same client (the server only do this)
  2. require to cater for 100 clients
  3. speed is an important factor, ie: even at 100 client connections, it should not be laggy.

For now I have been using C# async method, but I find that I always encounter laggy at around 20 connections. By laggy I mean taking around almost 15-20 seconds to get the result. At around 5-10 connections, time to get result is almost immediate.
Actually when the tcp server got the message, it will interact with a dll which does some processing to return a result. Not exactly sure what is the workflow behind it but at small scale you do not see any problem, so I thought the problem might be with my TCP server.

Right now, I thinking of using a sync method. Doing so, I will have a while loop to block the accept method, and spawn a new thread for each client after accept. But at 100 connections, it is definitely overkill.

Chance upon IOCP, not exactly sure, but it seems to be like a connection pool, as the way it handles tcp is quite like the normal way.

For these TCP methods I am also not sure whether it is a better option to open and close connection each time message needs to be passed. On average, message are passed from each client at around 5-10 min interval.

Another alternative might be to use a web, (looking at generic handler) to form only 1 connection with the server. Any message that needs to be handled will be passed to this generic handler, which then sends and receive message from the server.

Need advice from especially those who did TCP in large scale. I do not have 100 PC for me to test out, so quite hard for me. Language wise C# or C++ will do, I'm more familar with C#, but will consider porting to C++ for the speed.

A: 

I don't see why C# should be any worse than C++ in this situation - chances are that you've not yet hit upon the 'right way' to handle the incoming connections. Spawning off a separate thread for each client would certainly be a step in the right direction, assuming that workload for each thread is more I/O bound than CPU intensive. Whether you spawn off a thread per connection or use a thread pool to manage a number of threads is another matter - and something to determine through experimentation and also whilst considering whether 100 clients is your maximum!

Will A
OK, this I roughly guessed will be problem for spawning thread. Cause I believe that number of threads a PC is able to handle is proportionally to the number of CPU. But C# and C++, not sure the comparison, read online regarding IOCP,some say C# better, others commend on C++
C_Rance
Uhm, you should be using a thread pool, not spawning threads.
Steven Sudit
ne thread per client is stupid. Sorry - that blunt. IIS should be taken as example: que3ue requests, use a thread pool to handle requests.
TomTom
ok, thanks Steven. So can this link be considered as threadpool?http://msdn.microsoft.com/en-us/library/system.net.sockets.socketasynceventargs.aspx
C_Rance
+4  A: 

You must be doing it wrong. I personally wrote C# based servers that could handle 1000+ connections, sending more than 1 message per second, with <10ms response time, on commodity hardware.

If you have such high response times it must be your server process that is causing blocking. Perhaps contention on locks, perhaps plain bad code, perhaps blocking on external access leading to thread pool exhaustion. Unfortunately, there are plenty of ways to screw this up, and only few ways to get it right. There are good guidelines out there, starting with the fundamentals covered in Rick Vicik's High Performance Windows Programming articles, going over the SocketAsyncEventArgs example which covers the most performant way of writing socket apps in .Net since the advent of Socket Performance Enhancements in Version 3.5 and so on and so forth.

If you find yourself lost at the task ahead (as it seems you happen to be) I would urge you to embrace an established communication framework, perhaps WCF with a net binding, and use the declarative service model programming of WCF. This way you'll piggyback on the WCF performance. While this may not be enough for some, it will get you far enough, much further than you are right now for sure, with regard to performance.

Remus Rusanu
@Remus: I hope you won't mind a slightly off-topic question... Have you ever run into bugs in the new `Socket` async APIs?
Stephen Cleary
For what it's worth, properly configured WCF has proven to be quite fast.
Steven Sudit
Ok thanks, by far u give me the most guide.1st time dealing with 100 connections, and using the dll, not sure which is causing me the problems. But if you say yours can handle 1k plus connections, i guess it ties down to the dll.
C_Rance
Any since I am using async, is there any other way to hopefully improve it, given the number of connections that I have to handle? I have used SocketAsyncEventArgs in silverlight and grown to like it.
C_Rance
dun mind , but I also have another application which I am testing on socket async is actually using from the same sample u gave. just that when doing process send. I not very sure is what I'm doing correct. at this part:"Interlocked.Add(ref m_totalBytesRead, e.BytesTransferred);e.SetBuffer(e.Offset, e.BytesTransferred);//this just echo back"I interlock it then set the buffer to the string that i wants.e.SetBuffer(new_buffer,0, new_bufferlength);
C_Rance
@C_Rance: You can give a try to Sampled Profiling that comes with VS (aka. 'F1 Profiler'). See Find Application Bottlenecks with Visual Studio Profiler http://msdn.microsoft.com/en-us/magazine/cc337887.aspx.
Remus Rusanu
@Stephen Clearly: no, not really. Why, did you encounter any problem?
Remus Rusanu
@C_Rance: can you post, perhaps a new question, the relevant parts of the code?
Remus Rusanu
@C_Rance: and btw, at around 300-400 connections with repeated test runs you'll start hitting long delays due to TCP/IP port exhaustion. You need to edit the registry on the server, see http://blogs.technet.com/b/askds/archive/2008/10/29/port-exhaustion-and-you-or-why-the-netstat-tool-is-your-friend.aspx, http://msdn.microsoft.com/en-us/library/aa560610%28BTS.20%29.aspx and http://support.microsoft.com/kb/196271
Remus Rusanu
@Remus: No; I haven't used them at all yet. I've heard *rumors* of bugs under high-load conditions (all in the Desktop CLR, not SL), but haven't found any reproducible test cases.
Stephen Cleary
thanks very much guys, will do some profiling with Remus's link.Very kind of u guys to keep coming and guide me
C_Rance