Python 套接字刷新

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4407835/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 15:36:29  来源:igfitidea点击:

Python Socket Flush

pythonsockets

提问by Bob McLaury

I am trying to make sure that every time I call the socket.send function my buffer is sent (flushed) to my server (which is in C using unix socket).

我试图确保每次调用 socket.send 函数时,我的缓冲区都被发送(刷新)到我的服务器(在 C 中使用 unix 套接字)。

From my understanding (and from what I see on this board) just disabling the naggle algo. should do it but my server still receive my data in chunk of 4096 bytes (default set)...

根据我的理解(以及我在这个板上看到的)只是禁用了 naggle 算法。应该这样做,但我的服务器仍然以 4096 字节的块(默认设置)接收我的数据......

Im using the following code in Python v2.5.4:

我在 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...

Enabling/Disabling TCP_NODELAY seems that have no effect whatsoever... Is this a bug or I am missing something?

启用/禁用 TCP_NODELAY 似乎没有任何影响......这是一个错误还是我遗漏了什么?

TIA

TIA

回答by Greg Hewgill

TCP does not provide any kind of guaranteed "packet" sending to the other end. You are sending data as fast as you can, and TCP is helpfully batching up the data into as much as it can send at once. Your server is receiving data 4096 bytes at a time, probably because that's what it asked for (in a recv()call).

TCP 不提供任何类型的有保证的“数据包”发送到另一端。您正在尽可能快地发送数据,而 TCP 有助于将数据批量处理成一次可以发送的数量。您的服务器一次接收 4096 个字节的数据,这可能是因为它要求(在recv()通话中)。

TCP is a stream protocol and therefore you will have to implement some kind of framing yourself. There are no built-in message boundaries.

TCP 是一种流协议,因此您必须自己实现某种框架。没有内置的消息边界。

回答by xubuntix

There is no way to ensure the size of the data chunks that are sent. If you want to make sure that all the data that you want to send is send, you can close the connection:

无法确保发送的数据块的大小。如果要确保所有要发送的数据都已发送,则可以关闭连接:

self.sck.close()

Note also, that n = socket.send() returns the number of actual sent bytes. If you definitely want to send all data, you should use

另请注意, n = socket.send() 返回实际发送的字节数。如果你肯定想发送所有数据,你应该使用

self.sck.sendall()

or loop over the data sending:

或循环发送数据:

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

(But that is roughly the same as sendall() ). If you want to receive the data in bigger chunks, you can increase the size of the buffer in recv(), but this only makes the possible chunk size bigger. There is no guaranty that the data arrives in these sizes.

(但这与 sendall() 大致相同)。如果你想以更大的块接收数据,你可以在 recv() 中增加缓冲区的大小,但这只会使可能的块大小更大。无法保证数据以这些大小到达。

回答by Stuart Deal

The only way I got a flush to work (back to a C client) was to use:

我开始工作(回到 C 客户端)的唯一方法是使用:

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

The big advantage is that my_writer_obj defaults to text mode, so no more byte translation.

最大的优点是 my_writer_obj 默认为文本模式,因此不再需要字节转换。

creating a reader object did not go as smoothly, but I did not need a flush on that side.

创建一个 reader 对象并没有那么顺利,但我不需要在那一侧冲洗。

回答by alyaxey

This is a common question about TCP protocol. TCP itself has no way to send data in specific chunks. It's designed only for sending stream of data. If you need such functionality, you should implement it yourself. For example, send your chunks in separate lines or first send chunk size and then the chunk itself.

这是一个关于 TCP 协议的常见问题。TCP 本身无法以特定的块发送数据。它仅用于发送数据流。如果你需要这样的功能,你应该自己实现它。例如,在单独的行中发送您的块或首先发送块大小然后发送块本身。

In most cases, you don't need to care about the Naggle algorithm. This algorithm is better described by the name TCP_NODELAY. If you disable it, you may achieve smaller delays for small chunks but lower speed for large chunks at the same time.

大多数情况下,您不需要关心 Naggle 算法。这个算法最好用名称 TCP_NODELAY 来描述。如果您禁用它,您可能会为小块实现更小的延迟,但同时为大块实现更低的速度。