socket.send 是一种低级方法,基本上只是 C/syscall 方法send(3) / send(2)。它可以发送的字节数少于您请求的字节数,但会返回发送的字节数。
socket.sendall 是一种仅限 Python 的高级方法,用于发送您传递的整个缓冲区或引发异常。它通过调用socket.send 来做到这一点,直到所有内容都已发送或发生错误。
如果您正在使用带有阻塞套接字的 TCP 并且不想被打扰
通过内部(大多数简单的网络应用程序都是这种情况),
使用 sendall。
还有 python 文档:
与 send() 不同,此方法继续从字符串发送数据,直到
要么所有数据都已发送,要么发生错误。没有返回
成功。出错时会引发异常,并且 没有办法
确定成功发送了多少数据(如果有)
感谢 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 source):
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()