Когда возвращается socket.recv (recv_size)? - PullRequest
41 голосов
/ 24 августа 2011

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

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

  2. При поступлении некоторых данных размер данных превышает recv_size.

  3. Некоторые данные поступают, размер данных меньше, чем recv_size, и через короткое время больше не поступает никаких данных (я обнаружил, что 0,1 с будет работать).

Подробнее о # 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 эхо:

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

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

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

Верны ли мои выводы?Где можно посмотреть официальное описание о # 3?

Ответы [ 3 ]

21 голосов
/ 24 августа 2011

Да, ваш вывод верен. socket.recv является блокирующим вызовом.

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

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

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

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

4 голосов
/ 24 августа 2011

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

0 голосов
/ 05 апреля 2019

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

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

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

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