Python Socket Flush - PullRequest
       4

Python Socket Flush

5 голосов
/ 10 декабря 2010

Я пытаюсь убедиться, что каждый раз, когда я вызываю функцию socket.send, мой буфер отправляется (очищается) на мой сервер (который находится в C с использованием сокета unix).

Из моего понимания (и из того, что я вижу на этой доске) просто отключение naggle algo. должен сделать это, но мой сервер все еще получает мои данные в размере 4096 байт (по умолчанию) ...

Я использую следующий код в Python v2.5.4:

 self.sck = socket( AF_INET, SOCK_STREAM )

 self.sck.setsockopt( IPPROTO_TCP, TCP_NODELAY, 1 ) # That doesn't seems to work...

 self.sck.connect( ( "127.0.0.1", "12345" ) )

 while( 1 ):
      self.sck.send( "test\n" )
      self.sck.send( "" ) # Still trying to flush...

Включение / отключение TCP_NODELAY, похоже, не имеет никакого эффекта ... Это ошибка или я что-то упустил?

1010 * ТИА *

Ответы [ 4 ]

7 голосов
/ 10 декабря 2010

TCP не обеспечивает какой-либо гарантированной отправки "пакетов" на другой конец.Вы отправляете данные так быстро, как только можете, и TCP старательно объединяет данные в максимально возможное количество раз.Ваш сервер получает данные по 4096 байт за раз, вероятно, потому, что он запрашивал их (при вызове recv()).

TCP - это потоковый протокол, и поэтому вам придется реализовать какое-то создание самостоятельно.,Нет встроенных границ сообщений.

5 голосов
/ 19 июля 2014

Единственный способ получить флеш на работу (обратно к клиенту C) - использовать:

my_writer_obj = mysock.makefile(mode='w', ...)
my_writer_obj.write('my stuff')
my_writer_obj.flush()

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

создание объекта считывателя прошло не так гладко, но мне не потребовался сброс на этой стороне.

4 голосов
/ 10 декабря 2010

Нет способа гарантировать размер отправляемых фрагментов данных.Если вы хотите убедиться, что все данные, которые вы хотите отправить, отправлены, вы можете закрыть соединение:

self.sck.close()

Также обратите внимание, что n = socket.send () возвращает количество фактических отправленных сообщений.байт.Если вы определенно хотите отправить все данные, вы должны использовать

self.sck.sendall()

или циклически пересылать данные:

while data:
    n = self.sck.send(data)    
    data = data[n:]

(но это примерно то же самое, что sendall ()).Если вы хотите получать данные более крупными порциями, вы можете увеличить размер буфера в recv (), но это только увеличивает возможный размер порции.Нет гарантии, что данные поступают в таких размерах.

1 голос
/ 09 марта 2018

Это распространенный вопрос о протоколе TCP.Сам TCP не имеет возможности отправлять данные отдельными частями.Он предназначен только для отправки потока данных.Если вам нужен такой функционал, вы должны реализовать его самостоятельно.Например, отправляйте свои чанки отдельными строками или сначала отправляйте их размер, а затем сам чанк.

В большинстве случаев вам не нужно заботиться об алгоритме Naggle.Этот алгоритм лучше описывается именем TCP_NODELAY.Если вы отключите его, вы можете добиться меньших задержек для маленьких кусков, но одновременно снизить скорость для больших кусков.

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