为什么python套接字库不包含像sendall()这样的recvall()方法?

fly*_*ike 13 python sockets python-2.7

使用recv()方法时,有时我们无法接收到我们想要的数据,就像使用send()一样.但我们可以使用sendall()来解决发送数据的问题,如何接收数据呢?为什么没有这样的recvall()方法?

NPE*_*NPE 6

没有根本原因可以将这种功能作为标准库的一部分提供.事实上,至少有一次尝试添加recvall().

鉴于它可以很容易地实现为循环recv(),我不认为这是一个重大的遗漏.

  • 根据我过去几年用 [socket] 标签查看 python 问题的经验,这是一个重大遗漏。 (4认同)
  • 如果您自己在“recv”周围的循环中实现它,那么您可以以适合您的方式处理它的失败。弄清楚如果“recv”失败,“recvall”应该做什么是导致您链接到比目鱼的补丁的原因。 (2认同)

che*_*ner 5

send有额外的信息recv没有:有多少数据要发送。如果您有 100 个字节的数据要发送,sendall可以客观地确定第一次调用send发送的数据是否少于 100 个字节,并继续发送数据,直到所有 100 个字节都发送完毕。

当您尝试读取 1024 个字节,但只取回 512 个字节时,您无法知道这是因为其他 512 个字节被延迟而您应该尝试读取更多,还是只有 512 个字节在第一个读取地方。你永远不能说会有更多的数据要读取,从而recvall变得毫无意义。您最多可以决定您愿意等待多长时间(超时)以及您愿意在放弃之前重试多少次。

您可能想知道为什么从文件读取和从套接字读取之间存在明显的区别。对于文件,您可以从文件系统获得关于文件中有多少数据的额外信息,因此您可以可靠地区分 EOF 和其他一些可能阻止您读取可用数据的信息。套接字没有这样的元数据来源。

  • 如果您正在解析“类型,长度,值”协议,您*准确*知道您需要读取多少字节 - 首先足以读取类型和长度字段(其长度恒定),然后读取您知道有多大的值来自读取的标头。任何类型的问题都意味着消息格式错误,因此您可以安全地中止连接。 (3认同)
  • 除了你应该使用套接字库*仅*如果你使用非标准协议......即使HTTP也有指示主体大小的标头,并且标准库中也有类似ACSII的协议的规定(`socket.makefile ('r').readline()`)。很傻,二进制协议没有,你*有办法知道*阅读多少。 (2认同)
  • 而且我认为您不理解我们尝试在 Python 中执行此操作的事实。您应该问自己的第一件事是“Python 如何解决我的问题”,而不是尝试第 n 次重新发明轮子。无论您是图书馆还是应用程序开发人员。如果您正在编写基于 ASCII 的协议解析器,它确实为您提供了轮子,而不是二进制协议。 (2认同)