Как вы очищаете Python-сокеты? - PullRequest
       31

Как вы очищаете Python-сокеты?

12 голосов
/ 31 октября 2009

Я написал сервер на Python, который предназначен для отправки данных клиенту в форме «Заголовок: Сообщение»

Я бы хотел, чтобы каждое сообщение отправлялось индивидуально, чтобы клиенту приходилось выполнять минимальную работу, чтобы прочитать «заголовок» и «сообщение»

К сожалению, я не могу понять, как правильно очистить сокет python, поэтому, когда у меня несколько посылок, выполняются в быстрой последовательности, сообщения объединяются в буфере сокета и отправляются как один большой кусок.

Пример:

Сервер отправляет ...

socket.send ("header1:message1")
socket.send ("header2:message2")
socket.send ("header3:message3")

Клиент получает ... "Header1: message1header2: message2header3: message3"

Я бы хотел получить три отдельных сообщения

header1:message1
header2:message2
header3:message3

Мне нужен способ сбрасывать после каждой отправки

Ответы [ 3 ]

22 голосов
/ 31 октября 2009

Я полагаю, вы говорите по TCP-соединению.

Ваш подход некорректен. Поток TCP определяется как поток байтов. Вы всегда должны использовать какой-либо разделитель и не можете полагаться на сетевой стек для разделения ваших сообщений.

Если вам действительно нужны службы на основе дейтаграмм, переключитесь на UDP. В этом случае вам нужно будет самостоятельно выполнить повторную передачу.

Для уточнения:

Очистка буфера отправки обычно создает новые пакеты, как вы и ожидаете. Если ваш клиент читает эти пакеты достаточно быстро, вы можете получить одно сообщение за чтение.

Теперь представьте, что вы общаетесь по спутниковой связи. Из-за высокой пропускной способности и задержек последний маршрутизатор до sat ждет короткое время, пока в буфере не окажется достаточно данных, и отправит все ваши пакеты одновременно. Ваш клиент теперь получит все пакеты без задержки и поместит все данные в приемный буфер сразу. Значит, ваше разделение снова прошло.

2 голосов
/ 04 февраля 2011

просто добавить \n после каждого сообщения ... как

socket.send ("header1:message1\n")
socket.send ("header2:message2\n")
socket.send ("header3:message3\n")
1 голос
/ 01 ноября 2009

То, что вы пытаетесь сделать, это разбить ваши данные на «партии».

Например, вы работаете с «пакетами» всякий раз, когда читаете «строки» из файла. Что определяет «линию»? Это последовательность байтов, оканчивающаяся на \ n. Другой пример: вы читаете 64-килобайтные «куски» из файла. Что определяет «кусок»? Вы делаете, так как вы читаете 65536 байтов каждый раз. Вы хотите переменную длину "чанка"? Вы просто добавляете префикс "chunk" к его размеру, а затем читаете "chunk". Файлы «aiff» (реализациями которых также являются файлы .wav и .avi в MS Windows) и файлы «mov» организованы следующим образом.

Эти три метода являются наиболее фундаментальными для организации потока байтов, независимо от носителя:

  1. разделители записей
  2. записи фиксированного размера
  3. записей с префиксом их размера.

Они могут быть смешаны и / или изменены. Например, у вас могут быть «разделители записей переменных», например, для чтения XML: читать байты с первого «<» до первого «>», добавлять косую черту после первого «<» и вызывать его как конец записи, читать поток до в связи с прекращением записи. Это просто грубое описание. </p>

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

...