LINUX.ORG.RU

Странное дробление данных передаваемых через сокет

 ,


0

1

В общем проблема вот в чем: Есть клиент (Windows). Он подключается к серверу (Linux), отсылает ему 17 байт ЗА ОДИН SEND!!! У сервера стоит TCP_DEFER_ACCEPT на сокет (30 сек). т.е. логика такая, что accept сработает как только придет первый пакет данных от клиента или пока не истечет время 30 сек. И так вот - работает всё отлично. Если клиент за 30 сек не отправил данные, то значит это не правильный клиент.
Ну так вот, проблема в том, что сервер после accept делает:

Len = recv(Sock, &Pack, sizeof(PACKET), MSG_NOSIGNAL | MSG_DONTWAIT);
И получается так что приходит не полный пакет. т.е. Len = 14 байт, а не 17 байт. Как такое может быть?
У меня логика такая:

  1. После коннекта клиента буфер отправки на клиенте пуст и по этому 17 байт вместит точно.
  2. Так как все 17 байт отправляются за один send то значит 100% они попадут в буфер и не разобьются.
  3. Размер 17 байт по любому меньше размера окна TCP и размера буфера отправки, по этому по идее уйдут они в одном TCP пакете
  4. Сервер за счет TCP_DEFER_ACCEPT ждет появления данных.
  5. Как только пришли данные, то они считываются без блокирования сокета. Так как мы сразу знаем сколько данных придет и что они будут в одном tcp пакете то они всегда должны быть целиком получены, но увы на деле не так.

В 10% случаях данные считываются именно 14 байт, а не 17. Может дело в какой-то настройке в Linux ? Причем глюки начинаются когда идет нагрузка на сервер.


TCP — это протокол потоковой передачи данных, забудь уже про пакеты

anonymous
()

в TCP даже если ты надрочишь в локалке чтобы у тебя посылки не фрагментировались, то в интернете у тебя будет сода сгеммороем - любая железяка на пути может изнсиловать твои пакеты на маленькие кусочки или наоборот склеить

Deleted
()

Запомни раз и навсегда, никакими ухищрениями нельзя гарантировать что read будет читать кусами такого же размера которые были посланы. Если ты знаешь что у тебя 17 байт, читай 17 байт. Если не знаешь - отправляй длину. Точка.

slovazap ★★★★★
()

Stop doing that! Я видел пакеты в полкило, приходящее по байту. Программа сильно удивлялась, пришлось хачить.

DonkeyHot ★★★★★
()

Ну так жди следующие 3 байта, они должны скоро дойти, разве нет? Разве вообще можно ограничивать размер пакетов с флоу контролом?

maggotroot
()

Так как все 17 байт отправляются за один send то значит 100% они попадут в буфер и не разобьются.

Вот здесь неверное утверждение. TCP - поток, никто не гарантирует тебе, что ты прочитаешь посланные данные за 1 read.

Тем более на нагруженном сервере. Операции же не атомарные.

grondek
()

1-5. Фантазировать не надо. tcpdump в зубы серверу и клиенту.

Полистай «йон снейдер эффективное программирование tcp/ip». Эта книга нетрудная и быстро избавляет от иллюзий.

anto215 ★★
()

Данные тебе вообще могут по 1 байту на пакет приходить, имеют право :)

Harald ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.