https://docs.python.org/ja/3/howto/sockets.html
C'est un mémo quand je lis ceci.
Puisqu'il s'agit d'un vidage du cerveau lors de la lecture, il est recommandé à ceux qui veulent simplement connaître le contenu de lire directement le document.
python3.8.2
Pourquoi lire la documentation
――Je veux lire le document ici et connaître les fonctions qui sont réellement utiles à utiliser sans le savoir.
―― Cela fait environ 8 ans que j'ai commencé à utiliser python, mais je le fais dans une atmosphère, donc il y a encore des fonctionnalités que je ne connais pas.
――J'utilise flask ・ django et zmq occasionnellement, mais j'ai vécu en détournant les yeux de la programmation interne du socket.
«Quoi qu'il en soit, je veux savoir ce que fait une prise.
Aperçu
- La programmation générale des sockets, en particulier INET STREAM (c'est-à-dire IPv4 TCP), sera brièvement expliquée en écrivant en python.
――Je n'ai aucune idée de ce que vous dites à ce stade
- Ni la programmation des sockets ni la façon d'écrire en python ne sont expliquées en détail.
Vous devriez pouvoir obtenir suffisamment d'informations pour pouvoir l'utiliser sans gêne
Et cela
Note
histoire
--Socket a été inventé par Berkeley dans le cadre de BSD Unix et est devenu très populaire
Créer une socket
--Il existe des sockets respectivement côté client et côté serveur.
Comme c'est la même chose avec zmq, il semble que l'interface sera consciente du niveau de socket.
――Alors lisez en imaginant avec zmq
client side
client_socket.py
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("qiita.com", 80))
seulement ça. Facile
server side
server_side.py
#Créer une socket serveur
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.bind((socket.gethostname(), 80))
serversocket.listen(5)
# serving
while True:
clientsocket, address = serversocket.accept()
# threaded server
ct = client_thread(clientsocket)
ct.run()
C'est un peu plus, mais c'est assez simple.
--Dans la première ligne, le nom de la variable est serversocket, mais ce que vous faites est exactement le même que clientsocket.
- Une socket serveur est une personne qui crée une socket cliente qui parle (= envoie) au port d'écoute quand quelque chose s'y connecte ().
――Si vous y parvenez, vous continuerez à écouter
-Dans le contexte de descripteur lu hier, par exemple, lier une fonction à un objet s'attribue toujours le premier argument par défaut de la fonction. Qui était
--Bind here a également été interprété comme la même `` liaison ''
―― En d'autres termes, vous avez d'abord créé un socket de serveur anonyme et enregistré socket.gethostname () comme hôte à écouter.
- Par analogie avec l'exemple de descripteur, il semble y avoir quelque chose dans le monde qui ajuste dynamiquement la destination d'écoute sans liaison.
- De plus, clientsocket.connect passe l'hôte et le port, mais j'imagine que serversocket est censé le transmettre au nom le plus primitif utilisé ici par défaut.
Exemple de socket
――J'explique avec un exemple plus concret
- Le socket client généré côté serveur est le même que celui purifié côté client.
- Le flux susmentionné de connexion du client au serveur → le serveur génère une socket client → les sockets client se parlent est une conception abstraite à un niveau, pas les spécifications de la socket elle-même.
- L'exemple de code est un exemple facile à comprendre d'envoi et de réception de messages avec socket.
- Vous devez vous demander si vous avez envoyé tous les messages ou s'ils sont toujours dans la mémoire tampon du réseau.
――Le reste est similaire à zmq?
――Il est difficile de recevoir plusieurs messages et les pauses ne sont pas évidentes
--Plusieurs solutions et leurs problèmes sont présentés
――Cela semble une bonne solution d'envoyer la longueur au début, mais même si vous indiquez la longueur des données avec un nombre à 5 chiffres, par exemple, il n'est pas toujours possible de recevoir 5 caractères à la fois sur un réseau à forte charge.
Données binaires
- La conversion est requise pour différents endians
――Lors de l'envoi d'un grand nombre de longs, 0 équivaut à 4 octets pour long mais 2 octets pour ASCII.
―― Regardons attentivement les données et faisons une sélection
Déconnecter
- Lors de la déconnexion, à l'origine
shutdown ()
et close ()
- La bibliothèque python fait
shutdown (); close ();
uniquement avec close ()
--Et python se ferme automatiquement lorsque GC est terminé
――Mais si la douille meurt involontairement, l'adversaire peut se bloquer, il vaut donc mieux ne pas se fier à cela
Prise non bloquante
--Non-bloquant avec socket.setblocking (0)
- Contrairement au blocage des sockets, envoyer, recevoir, se connecter, accepter peut revenir sans rien faire
--Option 1: gérer la valeur de retour et l'erreur → Semble devenir fou
--Option 2: Utilisez select
--Si vous passez une liste de sockets à select.select, seuls ceux qui sont lisibles / inscriptibles seront retournés, vous pouvez donc utiliser les verbes ci-dessus avec eux.
la mise en oeuvre
J'ai jeté un coup d'œil à l'implémentation car c'était un gros problème
https://github.com/python/cpython/blob/3.8/Lib/socket.py#L213
--Si vous l'utilisez avec avec la syntaxe, il semble vous appeler à fermer lorsque vous quittez le contexte
- Lorsqu'il est utilisé par des humains, il serait préférable d'utiliser SocketIO ou create_server.
Impressions
«Je pense qu'il vaut mieux regarder autrement que INET et STREAM pour comprendre plus profondément.
«Je ne l'utiliserai pas directement à l'avenir, mais j'ai réalisé que zmq est une assez bonne abstraction.