tcp - получение num байтов - PullRequest
2 голосов
/ 10 марта 2009

В стандартных реализациях tcp (скажем, на bsd) кто-нибудь знает, возможно ли выяснить, сколько байтов было подтверждено удаленным хостом? Вызов write () для сокета возвращает количество записанных байтов, но я полагаю, что на самом деле это означает количество байтов, которое может поместиться в буфере tcp (не количество байтов, записанных в сеть, или количество заблокированных байтов). Или, может быть, я ошибаюсь ...

спасибо!

Ответы [ 4 ]

1 голос
/ 10 марта 2009

Я не знаю ни одного способа получить это, и это, вероятно, в любом случае бесполезно для вас.

Предполагая, что вы хотите знать, сколько данных было получено хостом, чтобы после потери соединения и повторного соединения вы могли начать отправку оттуда снова. Таким образом, данные ACK были подтверждены только ОС! Это не указывает, какие данные были получены вашей программой на другой стороне; в зависимости от размера получаемого там TCP-буфера ваша программа может отставать на сотни КБ. Если вы хотите узнать, сколько данных было получено и «использованными» программой, то получите их для отправки ACK уровня приложения

1 голос
/ 10 марта 2009

Если у вас NODELAY = false (это значение по умолчанию), когда вы вызываете send () с меньшим количеством байтов, чем в окне TCP, байты на самом деле не отправляются немедленно, поэтому вы правы. ОС немного подождет, чтобы узнать, вызовете ли вы другой send (), чтобы использовать только один пакет для передачи объединенных данных и избежать потери заголовка TCP.

Когда NODELAY = true, данные передаются при вызове send (), поэтому вы можете (теоретически) рассчитывать на возвращаемое значение. Но это не рекомендуется из-за дополнительной неэффективности сети.

В общем, если вам не нужна абсолютная точность, вы можете использовать значение, возвращаемое send (), даже когда NODELAY = true. Это значение не будет отражать непосредственную реальность, но через несколько миллисекунд оно будет изменяться (но также будет проверяться наличие потерянных соединений, поскольку последний отправленный вами блок данных мог быть потерян). Как только соединение будет корректно разорвано, вы можете доверять всем данным, которые были переданы. Если это не так, вы узнаете об этом раньше - либо из-за того, что соединение было внезапно прервано, либо из-за того, что вы получили ошибку, связанную с хранением данных (или любую другую).

0 голосов
/ 10 марта 2009

Возможно, вам повезет с TCP, если использовать ioctl(fd, TIOCOUTQ, &intval); для перевода исходящей очереди в intval. Это будет общая длина, хранящаяся в очереди, включая «записанную приложением», но еще не отправленную. Это все еще лучшее приближение, которое я могу себе представить на данный момент.

0 голосов
/ 10 марта 2009

Я думаю, что вы ошибаетесь, хотя это одно из тех мест, где я хотел бы взглянуть на конкретную реализацию, прежде чем ставить на нее серьезные деньги. Рассмотрим, однако, случай TCP-соединения, когда соединение сбрасывается сразу после исходного рукопожатия. Если бы возвращаемое число байтов было просто количеством буферизованных, было бы возможно, по-видимому, записать количество байтов, но они остались бы недоставленными; это нарушило бы свойство гарантии доставки TCP.

Обратите внимание, что это верно только для TCP; не все протоколы внутри IP предоставляют одинаковую гарантию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...