C# Server - TCP/IP Socket Efficiency

1.3k Views Asked by At

Good day all!

I am working on a open source server for a game that is closed source - the game operates using TCP/IP sockets (instead of UDP, doh...) So being a connection based protocal, I am contrained to work with this.

My current program structure (dumbed down):

Core Thread

  • Receive new connection and create a new client object.

Client Object

  • IOloop (runs on its own thread)

    • Get data from socket, process packets. (one packet at a time)
    • Send data buffered from other threads (one packet at a time)

The client will send data immediately (no delay) when it is it's own thread.


I am noticing a huge flaw with the program, mainly it sends data very slow. Because I send data packet by packet, synchronously. (Socket.Send(byte[] buffer))

I would like to send data almost immediately, without delay - asynchronously.

I have tried creating a new thread every time I wanted to send a packet (so each packet sends on it's own managed thread) but this was a huge mess.

My current system uses a synchronous sending with nagle algorithm disabled - but this has the flaw of bottlenecking - send one packet, send operation blocks until TCP to confirms, then send the next... I can issue easily 10 packets every 100ms, and if the packets take 400ms to send, this backs up and breaks. Of course on my Local host I don't get this issue.


So, my question: What would be the best way to send multiple small packets of data? I am thinking of merging the data to send at the end of every IO thread loop to one large byte buffer, to reduce the back and forth delay - but the obvious problem here is this undermines the nagle algorithm avoidance which I had hoped would stop the delays.

How does a synchronous send work? Does it block until the data is confirmed correctly received by the recipient as I believe? Is there a way I can do this without waiting for confirmation? I do understand the packets must all go in order and correctly (as per the protocol specification).

1

There are 1 best solutions below

1
D. Brumby On

I have done some research and I'm now using the current system:

Async send/receive operations with no threading, using AsyncCallbacks.

So I have the server start a read operation, then callback until done, when a packet is received, it is processed, then a new read operation will begin...

This method drastically reduces system overheads - thread pools, memory etc.

I have used some methods from the following and customised to my liking: https://msdn.microsoft.com/en-us/library/bew39x2a(v=vs.110).aspx

Very efficient, highly recommend this approach. For any TCP/IP network application low lag is very important and async callbacks is the best way to do it.