Python Socket 刷新

12 投票
6 回答
72908 浏览
提问于 2025-04-16 08:20

我想确保每次我调用socket.send函数时,我的缓冲区数据都能被发送到我的服务器(服务器是用C语言写的,使用的是Unix套接字)。

根据我的理解(以及我在这个论坛上看到的),只要禁用Nagle算法就可以做到这一点,但我的服务器仍然接收到4096字节(默认设置)大小的数据块……

我在使用Python 2.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似乎没有任何效果……这是个bug,还是我漏掉了什么?

谢谢大家!

6 个回答

6

没有办法确保发送的数据块的大小。如果你想确保所有想要发送的数据都能发送出去,你可以关闭连接:

self.sck.close()

另外,n = socket.send() 会返回实际发送的字节数。如果你确实想发送所有数据,应该使用:

self.sck.sendall()

或者循环发送数据:

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

(但这和sendall()差不多)。如果你想以更大的块接收数据,可以在recv()中增加缓冲区的大小,但这只是让可能的数据块大小变大,并不能保证数据会以这些大小到达。

7

我让数据顺利传输回C客户端的唯一方法是使用:

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

最大的好处是,我的写入对象默认是文本模式,这样就不需要再进行字节转换了。

创建读取对象的时候没那么顺利,不过我在那边不需要进行数据的刷新。

10

TCP并不能保证数据包一定会送到对方。你发送数据的速度尽可能快,而TCP会尽量把数据打包成一次能发送的最大量。你的服务器每次接收的数据是4096字节,这可能是因为它在一个recv()调用中请求了这么多。

TCP是一种流协议,所以你需要自己实现一些数据的边界。它并没有内置的消息边界。

撰写回答