2017-01-11 8 views
3

У меня проблема с получением данных от сервера к клиенту. У меня есть следующая клиентская функция, которая пытается получить данные с сервера. Данные, отправленные сервером с использованием функции socket.sendall (data), больше, чем buff_size, поэтому мне нужен цикл для чтения всех данных.Розетка. Как получить все данные с помощью socket.recv()?

def receiveAll (sock): 
    data = "" 
    buff_size = 4096 
    while True: 
     part = sock.recv (buff_size) 
     data + = part 
     if part <buff_size: 
      break; 
    return data 

Проблема, что происходит со мной в том, что после первой итерации (читай первый 4096MB), во втором программа блокируется в ожидании других данных в part = sock.recv (buff_size). Как мне сделать так, чтобы recv() мог продолжить чтение других отсутствующих данных? Спасибо.

+0

Ваш код может нести квадратичное поведение, что очень плохо. Вместо этого используйте список и '. '.join()'. –

ответ

2

Ваша интерпретация неверна. Ваш код считывает все данные, полученные с сервера. Он просто не знает, что он должен прекратить прослушивать входящие данные. Он не знает, что сервер отправил все, что у него было.

Прежде всего отметим, что эти линии

if part <buff_size: 
     break; 

очень неправильно. Прежде всего, вы сравниваете строку с int (в Python3.x, которая генерирует исключение). Но даже если вы имели в виду if len(part) <buff_size:, то это все еще неправильно. Потому что, прежде всего, может быть отставание в середине потоковой передачи, и вы будете читать только кусок, меньший, чем buff_size. Ваш код остановится.

Кроме того, если ваш сервер посылает содержание размера, являющегося кратным buff_size то if часть никогда не будет удовлетворен, и она будет висеть на .recv() навсегда.

Сторона примечания: не используйте точки с запятой ;. Это Python.


Есть несколько решений вашей проблемы, но ни из них может быть использованы правильно без модифицирующих на стороне сервера.

Как клиент, вы должны знать, когда прекратить чтение. Но единственный способ узнать это - сервер делает что-то особенное, и вы это поймете. Это называется протоколом связи. Вы должны добавить значение к данным, которые вы отправляете/получаете.

Например, если вы используете HTTP, то сервер отправляет этот заголовок Content-Length: 12345 перед телом, поэтому теперь, как клиент, вы знаете, что вам нужно только прочитать 12345 байт (ваш буфер не должен быть таким большим, но с этим вы узнаете, сколько раз вам нужно зацикливать, прежде чем читать все).

Некоторые двоичные протоколы могут отправлять размер содержимого в первые 2 или 4 байта, например. Это также можно легко интерпретировать на стороне клиента.

Простым решением является следующее: просто закройте сервер, чтобы закрыть соединение после отправки всех данных. Тогда вам нужно будет добавить в свой код отметку if not part: break.

+0

Спасибо, я попробовал, и это сработало –

 Смежные вопросы

  • Нет связанных вопросов^_^