如何导出TCP客户端的缓冲区以接受更多数据?
我有一个简单的TCP服务器和客户端。客户端接收数据:
received = sock.recv(1024)
这看起来很简单,但我不知道怎么接收比缓冲区大得多的数据。我尝试把数据分成小块,从服务器多次发送(在UDP中有效),但它只是告诉我管道坏了。
有什么建议吗?
3 个回答
0
请记住以下几点:
- 你的操作系统对TCP/IP套接字的缓冲区大小有自己的定义。
- TCP/IP数据包的最大大小通常是1500字节。
- 根据pydoc文档,4096字节是一个不错的缓冲区大小。
说到这里,能看到那行代码周围的内容会很有帮助。有几个因素可能会影响这个问题,比如你是使用select还是轮询,套接字是否是非阻塞的等等。
你发送数据的方式也很重要,尤其是当远程连接断开时。需要更多的细节。
1
迈克的回答是你需要的,但这种情况你可不想遇到。你应该设计一个传输协议,使用固定长度的字段来描述将要发送的数据量。这是一种 类型-长度-值 协议,你会在网络协议中反复看到它。这样可以让你的协议在未来面对意想不到的需求时也能保持有效,同时帮助你将网络传输问题和程序问题分开。
发送端的代码大概是这样的:
socket.write(struct.pack("B", type) #send a one-byte msg type
socket.write(struct.pack("H", len(data)) #send a two-byte size field
socket.write(data)
接收端的代码大概是这样的:
type = socket.read(1) # get the type of msg
dataToRead = struct.unpack("H", socket.read(2))[0] # get the len of the msg
data = socket.read(dataToRead) # read the msg
if TYPE_FOO == type:
handleFoo(data)
elif TYPE_BAR == type:
handleBar(data)
else:
raise UnknownTypeException(type)
最终你会得到一个传输消息的格式,看起来像这样:
struct {
unsigned char type;
unsigned short length;
void *data;
}
1
如果你不知道会有多少数据通过这个连接传过来,而且你只是想一直读取数据直到连接关闭,那么你需要把socket.recv()
放在一个循环里:
# Assumes a blocking socket.
while True:
data = sock.recv(4096)
if not data:
break
# Do something with `data` here.