Python 使用socket.recv()时,当没有更多字节可读取时,程序将挂起

Python 使用socket.recv()时,当没有更多字节可读取时,程序将挂起,python,sockets,recv,Python,Sockets,Recv,我在一个流中接收到几个二进制消息。根据消息中的ID和长度解析每个消息。我想阅读所有发送的消息;但是,如果我尝试接收的字节数超过发送的字节数,则程序将挂起,直到先前设置的socket.settimeout()为止 我想如何处理这个问题: while end_of_file == 0: header = socket.recv(6) if header == '': end_of_file = 1 不起作用,因为它总是希望再发送6个字节。除非服务器告诉客户端,否则客

我在一个流中接收到几个二进制消息。根据消息中的ID和长度解析每个消息。我想阅读所有发送的消息;但是,如果我尝试接收的字节数超过发送的字节数,则程序将挂起,直到先前设置的socket.settimeout()为止

我想如何处理这个问题:

while end_of_file == 0:
    header = socket.recv(6)
    if header == '':
        end_of_file = 1

不起作用,因为它总是希望再发送6个字节。

除非服务器告诉客户端,否则客户端不会知道服务器没有发送更多数据。这意味着

  • 要么服务器必须提前告诉客户机需要多少数据
  • 或者服务器将发送一些特殊数据,以表明不再有数据
  • 或者服务器应该关闭连接,这也表明没有更多的数据(即recv将返回)。请注意,这仅在存在连接时有效,即使用TCP但不使用UDP
    • 你自己说的:

      如果我尝试接收的字节数超过发送的字节数,程序就会挂断

      如果套接字在阻塞模式(默认模式)下运行,您所描述的是正常行为。您让它读取,它等待新数据到达

      如果你不想让它永远等待,你必须:

    • 如果在读取过程中发生异常,则调用并处理该异常

    • 用于检测套接字何时有待读取的数据,然后调用
      socket.recv()
      读取


    • 那是不对的。它并不是“总是期望再增加6个字节”。只要接收到一个字节,或者对等方关闭连接,它就会返回。在这两种情况发生之前,它都会阻塞。这是哪种语言?看起来有点像Python,但谁知道它没有标记。在本例中,服务器发送消息长度,后跟消息数据。因此,客户机知道每条消息需要多少字节。听起来消息头(包括消息长度)是6个字节。我不知道如何从发布的代码中推断出这种行为,但如果是这种情况,服务器将需要使用包含0作为编码长度的消息来完成数据流。客户机可以使用它来知道服务器已完成发送。这类似于HTTP中的分块传输。海报上说:“我在一个流中接收到几个二进制消息。每个消息都根据消息中的ID和长度进行解析。”。这意味着每条消息都有一个描述消息的标题。因此,客户机必须先读取标题(通常是固定大小的),然后根据标题上的内容读取消息。你是对的。虽然从这个描述中还不清楚服务器是否会发送最后一条记录来表示数据的结束,但不管是否发送。大多数协议没有,也没有必要。由于客户端正在逐个消息地读取消息,因此要么消息到达,要么套接字关闭。客户应做好这两方面的准备。在此期间,是的,套接字将在套接字空闲时阻止调用方,除非使用非阻塞语义。这就是套接字编程在每种语言和每种平台上的工作原理。select.select()如何工作?+它对你有用吗Windows@AK_阅读文档
      select()
      是所有支持BSD样式套接字的平台上的标准套接字函数,包括Windows、*Nix等。