Python Linux Netlink 接收缓冲区
当我尝试从一个 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 对消息大小有上限,你应该利用这个限制来接收消息。