Почему я не получаю все данные с моим неблокирующим сокетом Perl? - PullRequest
1 голос
/ 13 октября 2009

Я использую сокеты Perl в AIX 5.3, версия Perl 5.8.2

У меня есть сервер, написанный на сокетах Perl. Существует опция «Блокировка», которая может быть установлена ​​в 0 или 1. Когда я использую Blocking => 0 и запускаю отправку данных сервером и клиентом (5000 байт), я могу получить только 2902 байта за один вызов. Когда я использую Blocking => 1, я могу получить все байты за один вызов.

Так работают сокеты или это ошибка?

Ответы [ 2 ]

6 голосов
/ 13 октября 2009

Это фундаментальная часть сокетов - точнее, TCP , которая ориентирована на поток. ( UDP является пакетно-ориентированным.)

Вы никогда не должны предполагать, что вы получите столько данных, сколько запрашиваете, или что нет больше доступных данных. В основном больше данных может поступить в любое время, когда соединение открыто. (Вызов read / recv / what, вероятно, вернет определенное значение, означающее «другой конец закрыл соединение.)

Это означает, что вы должны разработать свой протокол, чтобы справиться с этим - если вы фактически пытаетесь передать отдельные сообщения от А до Б, есть два распространенных способа сделать это:

  • Префикс каждого сообщения длиной. Читатель сначала читает длину, затем продолжает читать данные, пока они не будут прочитаны столько, сколько нужно.
  • Иметь какой-либо терминатор / разделитель сообщений. Это сложнее, так как в зависимости от того, что вы делаете, вам, возможно, нужно знать о возможности прочтения начала следующего сообщения, пока вы читаете первое. Это также означает «понимание» самих данных в «читающем» коде, а не просто произвольное чтение байтов. Тем не менее, это означает, что отправителю не нужно знать, как долго сообщение перед отправкой.

(Другая альтернатива - иметь только одно сообщение для всего соединения - т.е. вы читаете, пока соединение не будет закрыто.)

2 голосов
/ 13 октября 2009

Блокировка означает, что сокет ждет, пока там не будет данных, прежде чем вернуться из функции получения. Вполне возможно, что крошечное ожидание в конце также попытается заполнить буфер перед возвратом, или это может быть просто проблема синхронизации. Также вполне возможно, что неблокирующая реализация возвращает по одному пакету за раз, независимо от того, существует больше одного или нет. Короче говоря, нет, это не ошибка, но конкретное «почему» - это старая отговорка «это зависит от реализации».

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