Je suis confus à propos des fonctions socket.send()
et socket.sendall()
en Python. D'après ce que j'ai compris de la documentationsend()
la fonction utilise TCP et la fonction sendall()
) utilise le protocole UDP pour l'envoi de données. I Sachez que TCP est plus fiable pour la plupart des applications Web car nous pouvons vérifier quels paquets sont envoyés et lesquels ne le sont pas. C’est pourquoi, je pense que l’utilisation de send()
fonction peut être plus fiable que la fonction sendall()
.
À ce stade, je voudrais demander quelle est la différence exacte entre ces deux fonctions et laquelle est la plus fiable pour les applications Web?
Merci.
socket.send est une méthode de bas niveau et se résume à la méthode C/syscall send (3) / send (2) . Il peut envoyer moins d'octets que ce que vous avez demandé, mais renvoie le nombre d'octets envoyés.
socket.sendall est une méthode de haut niveau réservée à Python qui envoie la totalité du tampon que vous avez transmis ou lève une exception. Il le fait en appelant socket.send
jusqu'à ce que tout soit envoyé ou qu'une erreur se produise.
Si vous utilisez TCP avec des sockets bloquants et que vous ne voulez pas être dérangé par des éléments internes (c'est le cas pour la plupart des applications réseau simples), utilisez sendall.
Et python docs:
Contrairement à send (), cette méthode continue à envoyer les données d'une chaîne jusqu'à ce que toutes les données aient été envoyées ou qu'une erreur se produise. Aucun n'est retourné en cas de succès. En cas d'erreur, une exception est déclenchée et il n'y a aucun moyen de déterminer combien de données , le cas échéant, ont été envoyées avec succès
Crédits à Philipp Hagemeister pour une brève description que j'ai eu dans le passé.
modifier
sendall
utiliser sous le capot send
- jetez un oeil à la mise en œuvre de cpython . Voici un exemple de fonction agissant (plus ou moins) comme sendall
:
def sendall(sock, data, flags=0):
ret = sock.send(data, flags)
if ret > 0:
return sendall(sock, data[ret:], flags)
else:
return None
ou de rpython (source 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()