socket.send 是一个低级方法,基本上只是 C/syscall 方法 send(3) / send(2)。它可以发送少于你请求的字节数,但会返回发送的字节数。
socket.sendall 是一个高级 Python-only 方法,它发送传递给它的整个缓冲区或抛出异常。它通过调用 socket.send
直到所有数据被发送或发生错误来实现。
如果您正在使用阻塞套接字的 TCP 并且不想被内部问题所困扰(这通常是大多数简单网络应用程序的情况),请使用 sendall。
Python 文档如下:
与 send() 不同,此方法继续从字符串发送数据,直到所有数据已发送或发生错误。成功时返回 None。在发生错误时,会引发异常,并且无法确定有多少数据已成功发送
感谢 Philipp Hagemeister 过去提供的简要描述。
编辑
sendall
在底层使用 send
- 查看 cpython 实现。这里是一个类似于 sendall
的示例函数:
def sendall(sock, data, flags=0):
ret = sock.send(data, flags)
if ret > 0:
return sendall(sock, data[ret:], flags)
else:
return None
或从rpython (pypy源代码)中获取:
def sendall(self, data, flags=0, signal_checker=None):
"""Send a data string to the socket. For the optional flags
argument, see the Unix manual. This calls send() repeatedly
until all data is sent. If an error occurs, it's impossible
to tell how much data has been sent."""
with rffi.scoped_nonmovingbuffer(data) as dataptr:
remaining = len(data)
p = dataptr
while remaining > 0:
try:
res = self.send_raw(p, remaining, flags)
p = rffi.ptradd(p, res)
remaining -= res
except CSocketError, e:
if e.errno != _c.EINTR:
raise
if signal_checker is not None:
signal_checker()
.send()
可能不会发送您提供的所有数据,而sendall()
不会返回,直到所有数据都已发送 - 但这可能需要更长时间。一般来说,除非您知道需要使用.send()
,否则应该使用sendall()
。 - Tom Dalton