Отправить точное количество байтов через сокет

Я читал, что в Erlang с помощью gen_tcp данные, передаваемые через сокет, могут быть объединены в один поток. Как я могу заставить сокет отправлять точно определенное количество байтов?

1 ответ

Решение

TCP - это потоковый протокол (в отличие от UDP, который ориентирован на пакеты), который, например, означает, что принимающее приложение не может определить, поступают ли доступные данные из одного или нескольких send() звонки на клиента.

Вы на самом деле не имеете никакого контроля над количеством байтов, отправляемых в пакете TCP, несколько send() вызовы могут привести к получению одного пакета TCP и одного send() вызов может привести к отправке нескольких пакетов TCP. Это контролируется стеком TCP ОС.

В Erlang вы можете использовать опцию сокета {packet, 1|2|4} в gen_tcp:connect а также gen_tcp:listen создать пакетно-ориентированную обработку данных TCP. Это вставляет префикс 1,2 или 4 байта к каждому send() и принимающая сторона (при условии, что это также Erlang и использует тот же {packet, N} опция) будет считывать данные до тех пор, пока не будет получено отправленное количество байтов, независимо от того, как сообщение было фрагментировано в пакеты TCP.

Вызов gen_tcp:recv будет блокироваться до тех пор, пока не будет прочитано ожидаемое количество байтов. И то же самое для сокетов активного режима, сообщение отправляется с ожидаемым количеством байтов.

Другие вопросы по тегам