Мне нужно получить два пакета отдельно - linux объединяет их в один и отправляет в приложение - PullRequest
1 голос
/ 09 марта 2020

Мое устройство подключено к TCP-серверу, который регулярно отправляет сердцебиение. Временами эти пакеты сердечного ритма поступают вместе с каким-то другим пакетом, и в программе, где я читаю по сокету, эти два пакета объединяются и читаются как один пакет, что вызывает проблемы приложения с логи приложения c. Для меня все еще возможно добавить некоторый обходной путь, но есть ли способ сказать ядру, что эти два пакета должны отправляться как отдельные пакеты, а не как один?

Logi c на сервере - принимает входящие подключений, когда устройство подключается, создает отдельный поток для связи с устройством, установлен TCP_NODELAY, я использую опрос перед чтением данных из сокета. В любой момент времени существует около 100 потоков.

1 Ответ

7 голосов
/ 09 марта 2020

TCP - это потоковый протокол. Вы должны не полагаться на границы пакетов для обнаружения границ сообщений. Пакеты могут быть объединены и разделены в любой точке операционной системой, сетевыми картами или промежуточными маршрутизаторами. Не ожидайте, что каждый системный вызов write() будет иметь соответствующий read().

Аналогично, вы не должны полагаться на целые принимаемые пакеты. Вы должны обрабатывать возможность частичного чтения. Вы можете получать частичные пакеты от вызовов read() в любое время.

Это стандартная практика для создания кадров сообщений на уровне приложения: префикс каждого сообщения с заголовком, который включает длину и, возможно, также идентификатор сообщения. Прочитайте длину и затем прочитайте это много байтов. Если вы не получите все запрошенные байты, l oop и попробуйте снова.

...