如何使用fcntl.ioctl()在TCP中的sendall()之后获取待处理数据的大小?

时间:2016-12-09 12:11:46

标签: python sockets tcp raspberry-pi

我试图在调用socket的sendall()之后在输出缓冲区中获取挂起的数据大小。 我在类中使用TCP(非阻塞)套接字。我在课堂上发送消息功能的代码如下:

def send_data(self, msg):
    try:
        status_of_send = self.client.sendall(msg)
        buffer = array.array('I', [0])
        pending = fcntl.ioctl(self.tcp_socket.fileno(), termios.TIOCOUTQ, buffer, True)
        print pending
    except socket.error as e:
        print 'Error while sending data: %s', e

在调用此函数时,错误发生如下:

TraceBack (most recent call last):
File "server.py", line 199, in send_date
pending = fcntl.ioctl(self.tcp_socket.fileno(), termios.TIOCOUTQ, buffer, True)
IOERROR: [Errno 22] Invalid argument

我检查了相同的错误,但根据链接为https://docs.python.org/3/library/fcntl.html#fcntl.ioctl的python文档,我使用相同的方法。但仍然是错误发生

任何人都可以帮我解决这个问题吗?

我正在使用平台内核v 3.18.7 -7+ 和python v 2.7.3

1 个答案:

答案 0 :(得分:0)

来自sendall documentation

  

将数据发送到套接字... 与send()不同,此方法继续从字符串发送数据,直到所有数据都已发送或发生错误。成功时返回None。出错时,会引发异常,并且无法确定成功发送了多少数据(如果有)。

话虽如此,status_of_send始终为None,它将发送整个msg。否则,将引发异常,您将无法查看它设置的数据量。

另一方面,我发现Guido van Rossum's email他声明你不应该使用带有非阻塞套接字的sendall。在互联网上搜索这个问题似乎证实了这一说法。

send可能无法发送所有消息。在这种情况下,您也不需要使用ioctl,因为send返回它发送的字节数。您可以像这样使用它(加上一些非阻塞检查):

def my_sendall(sock, message):
    bytes_sent = 0
    while bytes_sent < len(message):
        bytes_sent += sock.send(message[bytes_sent:])