TCP: Какому именно буферу задают размер ReceiveBufferSize и SendBufferSize, нужно ли их изменять в каком-то случае?

336
20 декабря 2016, 22:20

Например, в C# есть TcpClient.ReceiveBufferSize и TcpClient.SendBufferSize (по сути они основаны на системной функции setsockopt).

Хочу понять, на что они влияют, размер какого именно буфера они задают, ведь в ядре ОС и библиотеке WinSock явно не один буфер есть :)

Посмотрел, какие у них значения по умолчанию.
В Windows 8 (x64) они по умолчанию равны 65536.
В Windows Server 2003 (x64) - 8192.

Ситуация #1.
Попробовал создать сервер и клиент, работающие по такому алгоритму:
- клиент подключается к серверу
- сервер (Win2003) одним вызовом Write передает клиенту файл в 70000 байт (размер выбрал больше обоих буферов)
- клиент (Win8) ждет несколько секунд и только потом я вручную вызываю Read на клиенте, опять же пытаюсь считать 70000 байт одним вызовом Read
- при этом сетевое подключение стабильное
Результат: файл передается нормально read возвращает 70000 байт и действительно файл не поврежден. Значит, в этом случае размер буферов не влияет.

Ситуация #2.
А что будет при обрыве кабеля, который потом устранится и накопленные (в буфере?) байты должны отправиться приемнику и считаться? В этом случае не повлияет ли размер буфера?
То есть такой алгоритм:
- клиент подключился к серверу
- произошел обрыв кабеля
- а в это время клиент быстро сформировал массив в 70000 байт, вызвал Write, массив добавился в очередь (в какой-то буфер)
- и тут кабель быстро вернули на место, все произошло очень быстро, так что клиент и сервер не успели вылететь из-за "неподключенных сокетов", так что сервер начинает получать эти байты в сегментах и читать их
Но ведь их 70000, может таких Write даже N раз подряд было до того как кабель вернулся на место, а лимит буферов по умолчанию всего лишь 8192 и 65536, в любом случае меньше, чем 70000 и тем более 70000*N.

Вторую ситуацию я пока не моделировал, только собираюсь.

Насколько вам известно: что произойдет? Не будет ли потери накопленных данных в этом случае, не окажутся ли они в "черной дыре"?

И главный вопрос: стоит ли изменять размер этих буферов в расчете на очень нестабильное подключение? Или их не надо трогать без нужды?
Для чего вообще сделана возможность их трогать?
Производительность не столь важна, гигабайтов я передавать не планирую, и задержки даже в несколько секунд не страшны.

UPD: А вот еще в MSDN у WinSock в списке есть такая ошибка:

WSAENOBUFS 10055 No buffer space available. An operation on a socket could not be performed because the system lacked sufficient buffer space or because a queue was full.

Это в каких случаях бывает? И тот ли это буфер, размер которого задают те параметры?

READ ALSO
Иконка приложения в трее Win 10

Иконка приложения в трее Win 10

При добавлении в трей иконки приложения через метод Shell_NotifyIcon изображение иконки искажается, независимо от размеров изображений вico файле

305
Помогите исправить начало программы [требует правки]

Помогите исправить начало программы [требует правки]

Суть в том, что дана Матрица А(7,7) нужно построить вектор в(7) из элементов главной диагонали

255
Нужно ли удалять указатель на QRunnable

Нужно ли удалять указатель на QRunnable

Использую так называемый QThreadPool и закидываю в него указатель на QRunnableТакой код:

355