如何导出TCP客户端的缓冲区以接受更多数据?

0 投票
3 回答
1439 浏览
提问于 2025-04-16 05:18

我有一个简单的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.

撰写回答