Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Socket buffers the data it receives

Tags:

c#

sockets

I have a client .NET application and a server .NET application, connected through sockets.

The client sends a string of 20 or so characters every 500 milliseconds.

On my local development machine, this works perfectly, but once the client and the server are on two different servers, the server is not receiving the string immediately when it's sent. The client still sends perfectly, I've confirmed this with Wireshark. I have also confirmed that the the server does receive the strings every 500 milliseconds.

The problem is that my server application that is waiting for the message only actually receives the message every 20 seconds or so - and then it receives all the content from those 20 seconds.

I use asynchronous sockets and for some reason the callback is just not invoked more than once every 20 seconds.

In AcceptCallback it establishes the connection and call BeginReceive

handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);

This works on my local machine, but on my production server the ReadCallback doesn't happen immediately.

The BufferSize is set to 1024. I also tried setting it to 10. It makes a difference in how much data it will read from the socket at one time once the ReadCallback is invoked, but that's not really the problem here. Once it invokes ReadCallback, the rest works fine.

I'm using Microsofts Asynchronous Server Socket Example so you can see there what my ReadCallback method looks like.

How can I get the BeginReceive callback immediately when data arrives at the server?

--

UPDATE

This has been solved. It was because the server had a a single processor and single core. After adding another core, the problem was instantly solved. ReadCallback is now called immediately when the call goes through to the server.

Thankyou all for your suggestions!!

like image 788
Niels Brinch Avatar asked Aug 24 '13 12:08

Niels Brinch


People also ask

What is socket receive buffer?

The receive socket buffer size determines the maximum receive window for a TCP connection. The transfer rate from a sender can also be limited by the send socket buffer size. DEC OSF/1 currently uses a default value of 32768 bytes for TCP send and receive buffers.

Do sockets buffer?

each TCP / streams socket will have its own unique send & receive buffers. These buffers are necessary for it to handle resending, ack management, reassembly etc. in the background. each UDP / datagram socket will have its own receive buffer, but not necessarily a unique & persistent send buffer.

What happens when socket buffer is full?

As the receive buffer becomes full, new data cannot be accepted from the network for this socket and must be dropped, which indicates a congestion event to the transmitting node.

What is buffer size in socket programming?

The maximum send buffer size is 1,048,576 bytes. The default value of the SO_SNDBUF option is 32767. For a TCP socket, the maximum length that you can specify is 1 GB.


2 Answers

One approach might be to adjust the SO_SNDBUF option for the send side. SInce you are not running into this problem when both server/client are on the same box, it is possible that having a small buffer is throttling the send side since due to (a possible) slower sending rate between the servers. If the sender cannot send fast enough, then the send-side buffer might be filling up sooner.

Update: we did some debugging and turns out that the issue is with the application being slower.

like image 148
Manoj Pandey Avatar answered Sep 22 '22 12:09

Manoj Pandey


It might be that the Nagle algorithm is waiting on the sender side for more packets. If you are sending small chunks of data, they will be merged in one so you don't pay a huge TCP header overhead for small data. You can disable it using: StreamSocketControl.NoDelay See: http://msdn.microsoft.com/en-us/library/windows/apps/windows.networking.sockets.streamsocketcontrol.nodelay

The Nagle algorithm might be disabled for loopback and this is a possible explanation of why it works when you have both the sender and the receiver on the same machine.

like image 22
Gabi Turliu Avatar answered Sep 18 '22 12:09

Gabi Turliu