web-dev-qa-db-ja.com

socket.send()とsocket.sendall()の違いは何ですか?

Pythonのsocket.send()およびsocket.sendall()関数について混乱しています。 ドキュメントsend()関数から理解したように、関数はTCPプロトコルを使用し、sendall()関数はUDPプロトコルを使用してデータを送信します。 TCPは、どのパケットが送信され、どのパケットが送信されていないかを確認できるため、ほとんどのWebアプリケーションでより信頼性が高いことを知っています。そのため、send()sendall()関数よりも信頼性が高くなります。

この時点で、これら2つの機能の正確な違いは何ですか、またWebアプリケーションではどちらがより信頼性が高いのでしょうか?

ありがとうございました。

28
cengineer

socket.sendは低レベルのメソッドであり、基本的には単にC/syscallメソッド send(3) / send(2) 。あなたが要求したよりも少ないバイトを送信できますが、送信されたバイト数を返します。

socket.sendallは、渡すバッファ全体を送信するか、例外をスローするPython専用の高レベルのメソッドです。それは、すべてが送信されるかエラーが発生するまでsocket.sendを呼び出すことで行います。

TCPをブロッキングソケットで使用しており、内部に煩わされたくない場合(ほとんどの単純なネットワークアプリケーションの場合)、sendallを使用します。

そしてpython docs:

Send()とは異なり、このメソッドは、すべてのデータが送信されるかエラーが発生するまで、stringからデータを送信し続けます。成功すると何も返されません。エラーの場合、例外が発生し、正常に送信されたデータの量があるかどうかを判断する方法はありません

過去に手に入れた短い説明については、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()
49
kwarunek