如何在 Python 中的 recv 之前找出套接字中的多少字节?

How to find out how many bytes in socket before recv in Python?

我有一个 TCP 处理数据流。它一次需要 4096 个字节,但我需要一种方法在接收之前找出整个套接字的大小。这样我就可以确定在切换套接字之前套接字将被读取多少次。它还会通知这是该套接字的最后一次接收,以便我可以在 select 切换到另一个套接字可用之前对其进行一些处理。

def handle_tcp(self, sock, remote):  
    fdset = [sock, remote]  
    while True:  
        r, w, e = select.select(fdset, [], [])  
        # How to find out how much bytes need to be read from socket?
        if sock in r:  
            non_blocking_calculation()
            if remote.send(sock.recv(4096)) <= 0: break  
        if remote in r: 
            non_blocking_calculation() 
            if sock.send(remote.recv(4096)) <= 0: break  

Linux and WindowsFIONREAD(同义词 SIOCINQ) ioctl。

Python 在 socketfcntl 模块中限制了 ioctl 的支持,但在通常的 TCP 编程中,这样的 ioctl 并没有被广泛使用.通常你只是 setblocking(false) 并读取所有可用数据直到 BlockingIOError 引发。或者用 headers/markers 指定 size/bounds 来定义某种消息。

你先于我。按照 Igor Kalinosvkiy 的方式。您可以使用 FIONREAD 来执行此操作,也可以使用 MSG_PEEK 并继续阅读直到空。例如,在 select().

之后
import fcntl, termios, array, math
...
sock_size = array.array('i', [0])  # initialise outside While loop
if sock in r:
    fcntl.ioctl(sock, termios.FIONREAD, sock_size)
    count = ceil(sock_size[0] / float(BUF_SIZE))
    print("Socket size: {} and count: {}".format(sock_size[0], count)