Socket.send()和 Socket.sendall()之间的区别是什么?

我对 Python 中的 socket.send()socket.sendall()函数感到困惑。据了解,文件send()函数使用 TCP 协议,sendall()函数使用 UDP 协议发送数据。我知道 TCP 对于大多数 Web 应用程序来说更可靠,因为我们可以检查哪些数据包被发送,哪些数据包没有被发送。这就是为什么,我认为使用 send()功能比使用 sendall()功能更可靠。

在这一点上,我想问这两个函数之间的确切区别是什么,哪一个对于 Web 应用程序更可靠?

谢谢你。

111702 次浏览

Send 是一个底层方法,基本上只是 C/syscall 方法 发送(3)/发送(2)。它可以发送比您请求的更少的字节,但返回发送的字节数。

Sendall 是一个仅用于 Python 的高级方法,它发送您传递或引发异常的整个缓冲区。它通过调用 socket.send来实现这一点,直到发送完所有内容或出现错误为止。

如果您正在使用带有阻塞套接字的 TCP,并且不希望受到干扰 通过内部(这是大多数简单网络应用程序的情况) , 用 Sendall。

蟒蛇医生:

与 send ()不同,此方法继续从字符串发送数据,直到 已发送所有数据或发生错误。未返回任何数据 如果出现错误,将引发异常,并且 < strong > 没有办法 确定成功发送了多少数据 (如果有的话)

感谢 Philipp Hagemeister 对我过去的简要描述。

编辑

sendall在引擎盖下使用 send-看看 巨蟒的实现。下面是一个与 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()