pythonsocket.recv()方法如何知道已到达消息的末尾?

pythonsocket.recv()方法如何知道已到达消息的末尾?,python,sockets,recv,Python,Sockets,Recv,假设我使用1024作为客户端套接字的缓冲区大小: recv(1024) 让我们假设服务器要发送给我的消息由2024个字节组成。 我的套接字只能接收1024个字节。其他1000字节怎么了 recv方法是否会等待一定的时间(例如2秒)以获得更多数据,并在该时间跨度后停止工作?(即,如果剩余数据在3秒后到达,则套接字将不再接收数据?) 或 recv方法在收到1024字节的数据后会立即停止工作吗?(即,是否会丢弃其他1000字节?) 如果1.)是正确的。。。我是否有办法确定recv数据返回前应等待的时

假设我使用1024作为客户端套接字的缓冲区大小:

recv(1024)
让我们假设服务器要发送给我的消息由2024个字节组成。 我的套接字只能接收1024个字节。其他1000字节怎么了

  • recv方法是否会等待一定的时间(例如2秒)以获得更多数据,并在该时间跨度后停止工作?(即,如果剩余数据在3秒后到达,则套接字将不再接收数据?)
  • recv方法在收到1024字节的数据后会立即停止工作吗?(即,是否会丢弃其他1000字节?)
  • 如果1.)是正确的。。。我是否有办法确定recv数据返回前应等待的时间量,还是由系统确定?(即,我是否可以告诉套接字在停止等待更多数据之前等待5秒钟?)

    更新: 假设我有以下代码:

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((sys.argv[1], port))
        s.send('Hello, world')
        data = s.recv(1024)
        print("received: {}".format(data))
        s.close()
    
    假设服务器发送大小大于1024字节的数据。我能否确保变量“data”将包含所有数据(包括1024字节以外的数据)?
    如果我不能确定这一点,我将如何更改代码,以便始终确保变量“data”将包含从服务器发送的所有数据(在一个或多个步骤中)

    这取决于协议。有些协议(如UDP)发送消息,每个
    recv
    只返回一条消息。假设您具体谈论的是TCP,那么涉及到几个因素。TCP是面向流的,由于当前未完成的发送/接收数据量、线路上丢失/重新排序的数据包、延迟的数据确认以及Nagle算法(将一些小的发送延迟几百毫秒),其行为会随着客户机和服务器之间对话的进行而发生微妙的变化

    接收器只知道它正在获得字节流。它可以在任何recv上获取从1到完全请求的缓冲区大小的任何内容。在一端的发送呼叫和另一端的recv呼叫之间没有一对一的关联

    如果您需要确定消息边界,则由更高级别的协议来确定。以HTTP为例。它以一个\r\n分隔的头开始,然后有一个客户端预期接收的剩余字节计数。客户端知道如何读取标头,因为\r\n然后才知道下一个字节数。RESTful协议的部分魅力在于它们是基于HTTP的,而且其他人已经知道了这一点

    有些协议使用NUL来分隔消息。其他的可能有一个固定长度的二进制报头,其中包括任何变量数据的计数。我喜欢它在TCP之上有一个健壮的消息传递系统

    有关接收发生的情况的更多详细信息

    当您执行recv(1024)时,有6种可能性

  • 没有接收数据
    recv
    将等待收到数据。您可以通过设置超时来更改此设置

  • 有部分接收数据。你会马上得到那个角色的。其余部分要么已缓冲,要么尚未发送,您只需执行另一个recv即可获取更多内容(同样的规则也适用)

  • 有超过1024个字节可用。您将获得1024个数据,其余数据将在内核中缓冲,等待另一个接收

  • 另一侧已关闭插座。您将获得0字节的数据。0意味着您将永远无法获得该套接字上的更多数据。但是如果你一直要求数据,你会一直得到0字节

  • 另一侧已重置插座。你会得到一个例外

  • 还有一些奇怪的事情发生了,你会因此得到一个例外


  • 你告诉计算机接收1024字节的数据,它确实如此。它并不关心是否有更多的数据要读取。@ForceBru-recv可以返回1到1024字节(或0,表示recv管道已被另一端关闭)之间的任何内容。如果您要求1024字节,比如说44字节立即可用,那么您只能得到44字节。@ForceBru-您说它正好接收1024字节,但它没有。我正试图澄清这一点。@ForceBru你说“你告诉计算机接收1024字节的数据,它确实如此”。@ForceBru-引用:“你告诉计算机接收1024字节的数据,它确实如此。”这不是真的。它接收的字节可能少于1024个。“更少”不是“确切的”。我对您答案的理解是:在TCP级别上,我无法确定recv()的行为(即,它是否会在接收到一组数据后返回,或者是否会获取更多数据,但在x秒后停止等待)。也就是说,决定何时停止等待/读取的策略只能在更高级别上配置。。。。。。这种理解正确吗?是的,基本上正确。通常需要TCP之上的更高级别协议来了解如何处理数据。如果您使用UDP(或Unix数据报)套接字,则任何长于调用
    recv()
    时使用的缓冲区的数据都将被丢弃。如前所述,TCP(或流)套接字将为下一次
    recv()
    调用保留额外的数据。