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

后端 未结 1 338
再見小時候
再見小時候 2020-12-13 01:43

I\'m confused about socket.send() and socket.sendall() functions in Python. As I understand from the documentation send() function use

相关标签:
1条回答
  • 2020-12-13 02:27

    socket.send is 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.sendall is a high-level Python-only method that sends the entire buffer you pass or throws an exception. It does that by calling socket.send until everything has been sent or an error occurs.

    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.

    And python docs:

    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

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

    edit

    sendall use under the hood send - take a look on cpython implementation. Here is sample function acting (more or less) like 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):

    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()
    
    0 讨论(0)
提交回复
热议问题