Для отправки вам действительно нужен этот цикл, только если вы перевели сокет в неблокирующий режим.Если сокет находится в режиме блокировки (по умолчанию), sock.send()
не вернется, пока не отправит сообщение целиком или не получит ошибку.
Однако для получения нет аналога, поскольку TCP невключить границы сообщения в протокол.sock.recv()
возвращается, как только появятся какие-либо данные.
- Вызывайте
sock.recv()
в цикле, пока не получите все, что вам нужно.Подобно тому, как ваша подпрограмма отправки отправляет более короткие подстроки на каждой итерации, вы можете уменьшить размер аргумента recv()
на величину, которую вы уже прочитали.Так что это может выглядеть так:
def myrecv(self, size):
buffer = ''
while size > 0:
msg = self.sock.recv(size)
buffer += msg
size -= len(msg)
return buffer
Если вы поместите 4-байтовую длину перед каждым сообщением, вы можете сделать что-то вроде:
msgsize = int(myrecv(4))
message = myrecv(msgsize)
Вы могли бы сделать это, но это усложняет ситуацию.Вам нужно читать по одному символу за раз, проверяя разделители, или реализовывать буфер, в котором хранятся данные, которые вы прочитали, но еще не вернули вызывающей стороне, потому что это уже после конца текущего сообщения.Кроме того, если данные могут содержать разделители, вам необходимо их избежать.
Нет, recv(1024)
может вернуться, как только получит какие-либо данные, которых может быть меньшечем размер сообщения, которое было отправлено.Если он гарантированно вернет 1024 символа, он зависнет, если отправитель отправит только 500 символов, поскольку он ожидает оставшиеся 524 символа.