Несколько вопросов о свойствах TCP протокола

Допустим, Ethernet MTU равен 1500 байт. Посылаем в сокет 2048 байт. Вопросы будут несколько необычные.

Вычитаем из MTU размеры заголовков — 20 байт IPv4 и и 20 байт TCP. Для простоты примем, что IP заголовок предаётся без опций. Получается, что мы можем передать в одном Ethernet фрейме 1460 байт.
Далее упрощаем условия и подразумеваем, что передающая и принимающая стороны не поддерживают Selective Acknowledgement. Рассмотрим ситуацию, когда удалённый TCP стек имеет достаточно большое окно, способное принять 32 Кб.

Первый вопрос: поддерживает ли спецификация TCP протокола частичный приём пакета? Т.е. может ли удалённая сторона установить Acknowledgement Number, сигнализирующий приём данных размером меньше переданного пакета (меньше 1460 байт для рассматриваемого случая)?

Второй вопрос относительно надёжности передачи. Все источники утверждают, что TCP транспорт гарантирует доставку пакетов. В таком случае не понятен один момент. Вызов send() не гарантирует доставку данных, он возвращает количество данных, записанных в буфер передачи TCP стека. Но как узнать сколько байт было доставлено удалённой стороне? Понятно, что сам стек, принимая Acknowledgement Number, «знает», сколько данных принято удалённой стороной. Но вот прикладной программе, передавшей данные, не дано узнать — приняты ли данные или нет.
  • Вопрос задан
  • 3447 просмотров
Пригласить эксперта
Ответы на вопрос 4
@SkyKos
По первому вопросу — в заголовке TCP нет флага, сигнализирующего о фрагментации пакета (в отличие от IP), а также есть чексумма, которая не будет валидной в случае, если пакет принят не полностью. Фрагментацией пакетов занимается уровень IP.
Ответ написан
Комментировать
@SkyKos
По второму вопросу могу предположить, что стековая архитектура TCP/IP изолирует верхние уровни о знании деталей реализации нижних уровней. В том числе и данные о SYN/ACK значениях. В общем-то, приложению совсем не нужно знать, что там внизу происходит, иначе уровни стека TCP/IP будут зависеть от реализации соседних уровней, а этого быть не должно.
Ответ написан
Комментировать
@bondbig
Но как узнать сколько байт было доставлено удалённой стороне?
Прикладу знать об этом и не требуется, в этом-то и смысл. В TCP заложен контроль целостности пакетов, недоставленные пакеты (в т.ч. доставленные частично) будут ретрансмититься необходимое количество раз, до достижения таймаута TCP_EST.
Ответ написан
Комментировать
@amosk
2) Кроссплатформенного способа вроде нет.
В linux есть ioctl SIOCOUTQ который позволяет определить, сколько еще не отосланных (не подтвержденных) данных есть в буфере отправки.
В других ОСях наверно тоже что-то подобное есть.
Зная, сколько байтов мы отправили в сокет, и вычитая из них эти не отосланые, можно определить, сколько доставлено.

Хотя обычно прикладной протокол построен по принципу запрос-ответ.
Так что получая ответ на свой запрос вы получаете подтверждение доставки запроса.
Т.е. проблемы этой вобщем-то не существует.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы