Python, блокирующий recv, возвращает меньше данных, чем запрошено

У меня есть эхо-сервер на C и тестовый клиент на Python. Сервер имеет ограниченный буфер чтения, например 16 байт. Когда клиент отправляет более 16 байтов, он сначала прочитает 16, запишет обратно клиенту, а затем снова прочитает.

Я протестировал сервер с помощью telnet и получил ту же строку, что и ввод, даже если она длиннее 16 байт. Однако этот клиент Python не работает.

//data is initialized to be 20 bytes data
Len = 20
sock.setblocking(1)
sock.send(data)
recvdata = sock.recv(Len)
if(recvdata != data):
    print recvdata.encode('hex')
    print Len
    print data.encode('hex')

Этот клиент получает только первые 16 байтов, которые сервер записывает обратно. Журнал сервера показывает две записи (16 + 4). Вывод Python выглядит так

1234567890123456 //recvdata
20
12345678901234567890 //sent data

Я не знаю, почему это происходит. Почему блокирующий recv() возвращает меньше данных, чем запрашивается?


person Wei Shi    schedule 15.09.2011    source источник


Ответы (1)


Длина, которую вы указываете для recv, является максимальной, а не целевой. Нет никакой гарантии, что recv будет ждать получения Len байтов — он может вернуться, как только прочитает какие-либо данные.

На справочной странице для recv сказано: Вызовы receive обычно возвращают любые доступные данные вплоть до запрошенной суммы, а не ждут получения всей запрошенной суммы.

Если вам нужно прочитать заданное количество байтов, вам нужно вызвать recv в цикле и объединить возвращенные пакеты, пока вы не прочитаете достаточно.

person RichieHindle    schedule 15.09.2011
comment
Я думаю, что справочная страница предназначена для системного вызова unix. Это то же самое для python recv()? - person Wei Shi; 16.09.2011
comment
В общем, библиотечные функции Python с именами в формате unix-y представляют собой настолько тонкие оболочки, насколько это возможно, но при этом допускают независимое от платформы поведение. - person Karl Knechtel; 16.09.2011