Подтвердить что ты не робот

Когда возвращается socket.recv(recv_size)?

Из теста я пришел к выводу, что в следующих трех случаях возвращается socket.recv(recv_size).

  • После закрытия соединения. Например, клиентская сторона вызванный socket.close() или любая ошибка сокета, он вернется пустая строка.

  • Приходят некоторые данные, размер данных больше, чем recv_size.

  • Приходят некоторые данные, размер данных меньше recv_size, и больше данных не поступает через короткое время (я нашел, что 0.1s будет работать).

Подробнее о # 3:

#server.py

while True:
    data = sock.recv(10)
    print data, 'EOF'

#client1.py

sock.sendall("12345")
sock.sendall("a" * 50)

#client2.py

sock.sendall("12345")
time.sleep(0.1)
sock.sendall("a" * 50)

Когда я запускаю client1.py, server.py echos:

12345aaaaa EOF
aaaaaaaaaa EOF
aaaaaaaaaa EOF
aaaaaaaaaa EOF
aaaaaaaaaa EOF
aaaaa EOF

Когда я запускаю client2.py, server.py echos:

12345 EOF
aaaaaaaaaa EOF
aaaaaaaaaa EOF
aaaaaaaaaa EOF
aaaaaaaaaa EOF
aaaaaaaaaa EOF

Правильно ли мои выводы? Где я могу увидеть официальное описание о # 3?

4b9b3361

Ответ 1

Да, ваш вывод верен. socket.recv - блокирующий вызов.

socket.recv(1024) будет читать не более 1024 байтов, блокируя, если данные не будут прочитаны для чтения. Если вы не прочитали все данные, другой вызов socket.recv не будет заблокирован.

socket.recv также закончится пустой строкой, если соединение закрыто или произошла ошибка.

Если вы хотите неблокирующий сокет, вы можете использовать модуль выбора (немного сложнее, чем просто использовать сокеты), или вы можете использовать socket.setblocking.

У меня были проблемы с socket.setblocking в прошлом, но вы можете попробовать, если хотите.

Ответ 2

Он будет иметь такое же поведение, что и основной вызов recv libc, см. справочную страницу для официального описания поведения (или прочитать больше общее описание сокетов api).

Ответ 3

Я думаю, что ваши выводы верны, но не точны.

Как указывают документы, socket.recv в основном ориентирован на сетевые буферы.

Когда сокет блокируется, socket.recv будет возвращаться, пока в сетевых буферах есть байты. Если байтов в сетевых буферах больше, чем может обработать socket.recv, он вернет максимальное количество байтов, которое он может обработать. Если количество байтов в сетевых буферах меньше, чем может обработать socket.recv, он вернет все байты в сетевых буферах.