For example, in C # there are TcpClient.ReceiveBufferSize and TcpClient.SendBufferSize (in fact, they are based on the system function setsockopt).

I want to understand what they influence, what size of buffer they set, because in the kernel of the OS and the WinSock library there is clearly not one buffer :)

I looked at their default values.
In Windows 8 (x64), they are by default equal to 65536.
In Windows Server 2003 (x64) - 8192.

Situation # 1.
I tried to create a server and client using the following algorithm:
- the client connects to the server
- the server (Win2003) transfers the file to the client to 70000 bytes with one call (the size selected is larger than both buffers)
- the client (Win8) waits for a few seconds and only then I manually call Read on the client, again I try to read 70,000 bytes with one call to Read
- while the network connection is stable
Result: the file is transferred normally read returns 70000 bytes and indeed the file is not damaged. Hence, in this case, the size of the buffers is not affected.

Situation # 2.
And what will happen when the cable is broken, which will then be eliminated and the accumulated (in the buffer?) Bytes should go to the receiver and be considered? In this case, will the buffer size be affected?
That is the following algorithm:
- the client has connected to the server
- cable breaks
- and at this time the client quickly formed an array of 70,000 bytes, called Write, the array was added to the queue (in some buffer )
- and then the cable was quickly returned to the site, everything happened very quickly, so the client and the server did not have time to fly out because of the "unconnected sockets", so the server begins to receive these bytes in segments and read them
But after all, there are 70,000 of them; maybe such a Write even N times in a row was before the cable returned to its place, and the default buffer limit is only 8192 and 65536, in any case less than 70,000 and more than 70,000 * N.

I have not yet modeled the second situation, just going.

As far as you know: what will happen? Whether there will be a loss of accumulated data in this case, will they turn out to be in a “black hole”?

And the main question: is it worth it to change the size of these buffers for a very unstable connection? Or they do not need to touch without need?
Why is it even possible to touch them?
Performance is not so important, I do not plan to transfer gigabytes, and delays even in a few seconds are not terrible.

UPD: But still in MSDN, WinSock has the following error in the list:

WSAENOBUFS 10055 No buffer space available. There is no need for the system.

This is what happens? And is this the buffer whose size is set by those parameters?

    1 answer 1

    First of all, I’ll clarify that I work with Unix, so I won’t be able to clarify a lot about calls and properties in Win.

    Which buffer is given the size of ReceiveBufferSize and SendBufferSize

    Set the size of the receive and send buffers for the client or server socket, depending on what properties you apply to. (setsockopt (), similarly, sets the properties of some socket passed to it in the parameters). These buffers store data until they are read by the application.

    Should I change the size of these buffers for a very unstable connection? Or they do not need to touch without need? Why is it even possible to touch them?

    Well, for example, you know: Your server always sends a data packet to the client, the size of which is always more than 10 Kb. I would like the client to always receive this package as a whole, and proceed to processing, rather than hanging in read (). Or another example: You know for sure that a packet of 10 KB on the server is being calculated right now, and you want to send it to the client as quickly as possible. If the server's send buffer on the server is only 4 KB, then sending the entire pack immediately fails, and the server will wait in write () until the client starts reading this data and the space in the buffer becomes free.
    Thus, it is an opportunity to optimize data transfer performance. If the socket buffers are small, the performance may be lower than expected (the high bandwidth channel will not be full). Large buffer sizes are required in high bandwidth channels.

    Whether there will be a loss of accumulated data in this case, will they turn out to be in a “black hole”?

    If everything that you describe in situation 2 happened “so quickly”, then there should be no data loss - TCP should take care of this, for that and a reliable protocol. It is possible that with active data exchange between the client and the server, the system will not share your opinion about “so quickly resolving the cliff”, in this case, the read () or write () calls will return an error or the number of bytes read / read is less than expected, need to handle.

    But after all, there are 70,000 of them; maybe such a Write even N times in a row was before the cable returned to its place

    write (), like read (), the blocking system call, and it will try to write all the data if there is no critical error or the socket has not been marked as non-blocking. If the record failed for some reason, write will return an error or the value of the number of bytes that he was able to write will not write too much to anywhere.

    WSAENOBUFS 10055 No buffer space available. There is no need for the system.

    This is what happens? And is this the buffer whose size is set by those parameters?

    Yes, the buffer is exactly that. This can occur, for example, on the server side, if the client slowly reads the data, and the server sends it too quickly, and its socket sending buffer overflows. It is possible that the same message will occur if the receiving client's socket buffer is smaller than the socket's send buffer on the server, and the server writes there at a time more data than the size of the socket's send buffer allows.