Python Linux Netlink 接收缓冲区

1 投票
1 回答
2996 浏览
提问于 2025-04-17 12:42

当我尝试从一个 NETLINK_ROUTE 套接字使用 socket.recv() 接收数据时,如果我没有接收到所有可用的数据,似乎没有接收到的数据就会丢失。

举个例子:

>>> import socket
>>> sock = socket.socket(socket.AF_NETLINK, socket.SOCK_DGRAM, socket.NETLINK_ROUTE)
>>> sock.bind((0,0))
>>> sock.send('\24\0\0\0\22\0\1\3\23\0364O\0\0\0\0\21\0\0\0') # struct nlmsghdr
20
>>> sock.recv(10000)
'\xe4\x03\x00\x00 ... ' (+3000 more bytes)

如果我使用 sock.recv(100),它会返回 100 字节的数据,但另外 +2900 字节的数据就消失了。再调用一次 sock.recv() 会返回下一个 nlmsghdr(如果是多部分消息的话),或者会阻塞,等待数据到来。

我可以使用 sock.recv(X, socket.MSG_PEEK) 来读取 X 字节的数据,而不会丢失数据;但这样读取的数据当然不会从接收缓冲区中移除。

我原以为任何未读取的数据会一直保留在缓冲区,直到被读取。那我到底做错了什么呢?我不想只是“猜测”可能有多少数据可用……

1 个回答

2

这就是数据报(SOCK_DGRAM 套接字)工作的方式——它会保持消息的边界,如果你没有读取整个数据包,剩下的部分就会被丢弃(而 SOCK_STREAM 套接字,也就是 TCP,提供的是字节流服务,你可以一次读取任意数量的字节,剩下的会保存在套接字缓冲区中)。

Netlink 提供了一种数据报服务,你可以用 SOCK_DGRAM 或 SOCK_RAW 套接字来使用它。

问题是什么呢?据我所知,netlink 对消息大小有上限,你应该利用这个限制来接收消息。

撰写回答