Python Socket 刷新
我想确保每次我调用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是一种流协议,所以你需要自己实现一些数据的边界。它并没有内置的消息边界。