【发布时间】:2011-10-20 06:30:16
【问题描述】:
Python 文件对象有一个 read 方法,它接受一个可选的 size 参数,它基本上是要返回的最大字节数。例如:
fname = "message.txt"
open(fname, "w").write("Hello World!")
print open(fname).read() # prints the entire file contents
print open(fname).read(5) # print "Hello"
print open(fname).read(99) # prints "Hello World!"
因此,即使我们的文件少于 99 个字符,对 read(99) 的调用也会立即返回所有可用数据。
我想在从socket.makefile 返回的文件对象上获得这种行为。但如果我说:
import socket
ADDR = ("localhost", 12345)
listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
listener.bind(ADDR)
listener.listen(1)
client = socket.create_connection(ADDR)
cf = client.makefile("r+b", bufsize=0)
server, client_addr = listener.accept()
sf = server.makefile("r+b", bufsize=0)
sf.write("Hello World!")
sf.flush()
print cf.read(99) # hangs forever
根据socket.makefile 文档,“可选模式和 bufsize 参数的解释方式与内置 file() 函数的解释方式相同。” 但我的原始文件示例即使在我说open(fname, "r+b", 0),而我想不出一种方法来使用套接字伪文件将所有可用数据返回到指定字节数。
如果我只使用socket.recv,这似乎效果很好:
import socket
ADDR = ("localhost", 12345)
listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
listener.bind(ADDR)
listener.listen(1)
client = socket.create_connection(ADDR)
server, client_addr = listener.accept()
server.sendall("Hello World!")
print client.recv(99) # prints "Hello World!"
那么有什么方法可以让socket.makefile 工作,或者这种“高级”功能根本不可用?
编辑: Python 3.2 似乎表现正确,但 socket.makefile 的参数语法似乎已更改:
import socket
ADDR = ("localhost", 12345)
listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
listener.bind(ADDR)
listener.listen(1)
client = socket.create_connection(ADDR)
cf = client.makefile("rwb", buffering=0)
server, client_addr = listener.accept()
sf = server.makefile("rwb", buffering=0)
sf.write(b"Hello World!")
sf.flush()
print(cf.read(99)) # prints "Hello World!"
我还没有深入研究源代码来弄清楚这两个版本之间的区别,但这可能是一个提示。
【问题讨论】:
-
@BrandonRhodes 我相信这是关闭套接字
sock.shutdown(SHUT_WR)的另一种可行选择