Python socket.send() 和 socket.sendall() 有什么区别?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34252273/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 14:41:58  来源:igfitidea点击:

What is the difference between socket.send() and socket.sendall()?

pythonsockets

提问by cengineer

I'm confused about socket.send()and socket.sendall()functions in Python. As I understand from the documentationsend()function uses TCP protocol and sendall()function uses UDP protocol for sending data. I know that TCP is more reliable for most of the Web Applications because we can check which packets are sent and which packets are not. That's why, I think use of send()function can be more reliable rather than sendall()function.

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

At this point, I want to ask what is the exact difference between these two functions and which one is more reliable for web applications?

说到这里,我想问一下这两个功能到底有什么区别,哪个对于web应用更可靠?

Thank you.

谢谢你。

采纳答案by kwarunek

socket.sendis a low-level method and basically just the C/syscall method send(3)/ send(2). It can send less bytes than you requested, but returns the number of bytes sent.

socket.send是一种低级方法,基本上只是 C/系统调用方法send(3)/ send(2)。它可以发送比您请求的更少的字节,但返回发送的字节数。

socket.sendallis a high-level Python-only method that sends the entire buffer you pass or throws an exception. It does that by calling socket.senduntil everything has been sent or an error occurs.

socket.sendall是一种高级 Python 专用方法,它发送您传递的整个缓冲区或引发异常。它通过调用socket.send直到所有内容都已发送或发生错误来做到这一点。

If you're using TCP with blocking sockets and don't want to be bothered by internals (this is the case for most simple network applications), use sendall.

如果您正在使用带有阻塞套接字的 TCP 并且不想被内部结构打扰(大多数简单的网络应用程序都是这种情况),请使用 sendall。

And python docs:

和 python 文档:

Unlike send(), this method continues to send data from string until either all data has been sent or an error occurs. None is returned on success. On error, an exception is raised, and there is no way to determine how much data, if any, was successfully sent

与 send() 不同,此方法继续从字符串发送数据,直到所有数据都已发送或发生错误为止。成功时不返回任何内容。出错时,会引发异常,并且无法确定成功发送了多少数据(如果有)

Credits to Philipp Hagemeister for brief description I got in the past.

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

edit

编辑

sendalluse under the hood send- take a look on cpythonimplementation. Here is sample function acting (more or less) like sendall:

sendallsend幕后使用- 看看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

or from rpython (pypy source):

或来自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()