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

时间:2015-12-13 14:41:04

标签: python sockets

我对Python中的socket.send()socket.sendall()函数感到困惑。据我所知,the documentation send()函数使用TCP协议,sendall()函数使用UDP协议发送数据。我知道TCP对于大多数Web应用程序来说更可靠,因为我们可以检查哪些数据包是发送的,哪些数据包不是。这就是为什么我认为使用send()函数可以更可靠而不是sendall()函数。

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

谢谢。

2 个答案:

答案 0 :(得分:46)

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

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

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

和python docs:

  

与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()

答案 1 :(得分:-11)

正如您已经提到的文档所述, send() 适用于 TCP sendall() 适用于 UDP

为了理解这两个函数之间的区别,您只需知道 TCP et UDP 之间的区别;意味着 send() 会跟踪发送到目标(服务器)的字节数,只有当我的服务器收到所有buffer_size时,其指令才会成功完成,为此,客户端需要连接到服务器以获取有关ACK的信息。

BUFFER = "a string"
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((target_host, target_port))
client.send(BUFFER)

对于 sendall() ,它只是将缓冲区发送到目标(服务器),而不知道服务器是否真正接收到此缓冲区的信息或不

BUFFER = "a string"
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.connect((target_host, target_port))
client.sendall(BUFFER, (target_host, target_port))
希望有所帮助!