socket.send è un metodo di basso livello e in pratica solo il metodo C/syscall send(3)/send(2). Può inviare meno byte di quanto richiesto, ma restituisce il numero di byte inviati.
socket.sendall è un metodo di alto livello solo Python che invia l'intero buffer passato o genera un'eccezione. Lo fa chiamando socket.send
fino a quando tutto è stato inviato o si verifica un errore.
Se si utilizza TCP con zoccoli di blocco e non si vuole essere disturbati da interni (questo è il caso per la maggior parte delle semplici applicazioni di rete), utilizza sendall.
e Python docs:
differenza send(), questo metodo continua a inviare i dati da stringa fino sia tutti i dati sono stati inviati o si verifica un errore. Nessuno viene restituito al successo . In caso di errore, viene sollevata un'eccezione, e non v'è alcun modo per determinare la quantità di dati, se del caso, è stato inviato con successo
Crediti Philipp Hagemeister per breve descrizione ho avuto in passato.
modificare
sendall
uso sotto il cofano send
- date un'occhiata su cpython attuazione. Ecco funzione di esempio agendo (più o meno) come sendall
:
def sendall(sock, data, flags=0):
ret = sock.send(data, flags)
if ret > 0:
return sendall(sock, data[ret:], flags)
else:
return None
o da 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()
La documentazione è abbastanza chiara IMO - '.send()' potrebbe non inviare tutti i dati che gli vengono dati, mentre 'sendall()' non ritornerà finché non saranno stati inviati tutti i dati - ma questo potrebbe richiedere più tempo. In generale si dovrebbe usare 'sendall()' a meno che non si sappia che è necessario usare '.send()'. –