0
votes

Comment utilisez-vous des prises UNIX à Python?

Je veux utiliser des prises UNIX pour 2 programmes Python sur le même système pour se parler.

Il existe des exemples de liaison à un fichier de socket ici: https://gist.github.com/ jmhobbs / 11276249

La bibliothèque Socketserver souvent utilisée possède également un UnixstreamServer et un UnixDatagramServer, qui ressemble également à des prises UNIX, mais il n'y a pas d'exemples de l'un ni autant que je puisse dire, cela nécessite une adresse IP et port plutôt qu'un fichier lors de l'initialisation d'un UnixstreamServer ou d'unixDatagramServer.

Sont UnixDatagramServer et Unixstreamserver un type différent de sockets UNIX qui ont démontré ici ? Ou est-ce que je ne vois tout simplement pas comment les utiliser pour se connecter correctement à un fichier de socket? Existe-t-il des exemples? Pourquoi quelqu'un utiliserait-il UNIXDATAGRAMSERVER / UNIXSTREAMSERVER sur la liaison à un fichier de socket directement, comme dans mon lien?

Et lorsque vous parlez de sockets IP, la différence entre TCP / UDP est logique - une est fiable, tandis que l'autre n'est pas, sans les frais généraux. Dans un monde de prises, où je suppose qu'il n'y a pas de communication peu fiable, pourquoi y a-t-il encore 2 types différents (Datagramme vs flux)?


0 commentaires

3 Réponses :


-1
votes

pour 2 programmes Python sur le même système à se parler

N'utilisez pas de sockets. Utilisez des tuyaux.

Une prise, en particulier, est essentiellement une liaison entre la couche d'application et la couche de transfert, dans la mise en réseau. C'est pourquoi vous avez besoin de fournir un numéro IP et de port - ce sont les informations adressées importantes pour quiconque en regardant votre ordinateur à l'extérieur. C'est également pourquoi vous avez des datagrammes vs flux - TCP et UDP sont les deux principaux protocoles de la couche de transport, et lorsque vous construisez votre lien vers la couche de transport, vous devez spécifier le protocole que vous souhaitez utiliser. Les sockets sont destinés à la communication à l'aide du réseau - il existe des moyens de communiquer entre deux processus sur le même système.

Les tuyaux sont plus comme des descripteurs de fichiers utilisés spécifiquement pour la communication inter-processus. Il existe essentiellement deux façons d'utiliser des tuyaux - des tuyaux nommés et des tuyaux anonymes. Si vos "deux programmes Python" se divèvent d'un programme original à l'aide de quelque chose comme multiprocessionnaire , les tuyaux anonymes sont ce que vous voudrez peut-être aller avec et vous pouvez utiliser OS.Pipe () pour définir cela. Sinon, vous devrez trouver un nom cohérent et un emplacement pour votre tuyau que les deux programmes connaissent et l'initialisent à une extrémité avec OS.MKFIFO () puis ouvrez-le comme un fichier ordinaire de l'autre extrémité. Cette fonctionnalité semble être disponible uniquement sur UNIX, donc si vous êtes sous Windows, vous pourriez avoir à enquêter sur autres solutions .


9 commentaires

Je me demande si cela commencera une guerre. J'ai suggéré quelque chose de similaire lorsque quelqu'un utilisait plusieurs adresses de bouclage IPv4 ( 127.0.0.0/8 ) pour la communication inter-processus et voulait la même chose pour IPv6, qui n'a qu'une seule adresse de bouclage ( :: 1 ), mais j'ai été châtonné que la pile de réseau est beaucoup plus rapide que les autres méthodes IPC. Je ne suis pas sûr que je crois que parce que cela implique trop d'autres processus, à la fois sur le chemin "Out" et sur le chemin "In.".


@Ronmapin, je suppose que vous peut utiliser l'adresse de bouclage (et écouter un port particulier), mais cela semble très semblable à appliquer le mauvais outil pour la situation. Je n'ai pas fait des tests de vitesse moi-même, mais je doute que le bouclage soit extrêmement plus efficace que le protocole de fichiers. Semble aussi être le genre de chose si vous vous en préoccupez alors vous ne poseriez pas cette question


" Cela semble très semblable à appliquer le mauvais outil pour la situation. " Je suis d'accord, mais j'ai été fortement dit sans des termes incertains que je me suis trompé. Il semble simplement si inefficace d'attribuer des adresses de bouclage individuelles aux processus, puis utilisez la pile réseau pour la communication. La personne qui demande la question aurait dû ré-archiver la totalité de la chose pour le faire fonctionner avec IPv6, et ce n'était pas celui qui m'a eu pour suggérer que cela ait été mal fabriqué à la première place.


Dans la liaison GitHub Gist ci-dessus, l'exemple utilise clairement un fichier, plutôt qu'un IP / port, et utilise le module de socket pour la définir, impliquant une prise, et non un tuyau, est utilisé. Votre réponse semble suggérer que les sockets utilisent toujours la couche de transfert de réseau, que l'exemple ne le fait pas. Quelque chose ne sonne pas bien. Le gist utilise-t-il réellement des tuyaux plutôt que des sockets (provenant d'un module malheureusement nommé)? Pourquoi y a-t-il des fichiers de socket Unix si les sockets utilisent toujours la pile de réseautage?


@John Je n'ai pas fait la lecture nécessaire, mais je supposerais que les sockets UNIX sont représentées comme des fichiers afin que les programmes puissent interagir avec eux à l'aide de protocoles d'E / S de fichier à partir de la couche d'application. Qui est la même chose avec des tuyaux, en fait.


@Greenloakguy Votre réponse commence avec Ne pas utiliser les sockets. Utilisez des tuyaux. et votre argument à remonter ce problème est que les sockets utilisent toujours la pile de réseau, tandis que les tuyaux ne le font pas. Le gist est clairement un exemple de sockets UNIX qui n'utilisent pas la pile de réseau, mais en utilisant des fichiers, qui semble compromettre votre argument. Je ne veux pas critiquer - seulement pour comprendre. Est-ce que je manque quelque chose? On dirait que des sockets Unix sont aussi efficaces que des tuyaux à cet égard si elles utilisent tous les deux des fichiers.


@John Quel est votre argument pour les sockets n'utilisant pas la pile de réseau? Ils sont - lorsque le gist envoie des informations avec Client.Send () , il s'agit de la couche de transport, codée dans le format de datagramme approprié et qu'on ne passe pas. Probablement également le haut de la couche de réseau avant de comprendre qu'il est censé boucler. Le serveur reçoit via la prise en utilisant le même protocole de transport de transport. L'abstraction est en place au profit du programmeur, pas parce que la même chose se passe en dessous du capot.


Ce n'est pas qu'ils utilisent des fichiers , c'est que vous les les accède via des descripteurs de fichier , ce qui n'est pas la même chose.


@Greenloakguy OK - Je suis. Logique. Merci



0
votes

Comme @greencloakguy a souligné, vous pouvez utiliser des tuyaux, mais si vous êtes prêt à utiliser des prises UNIX, voici un exemple approximatif d'utiliser StreamRequestHandler:

serveur: P>

#!/usr/bin/env python3

import socket
import sys 
import time

with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as client:
    client.connect("/tmp/test")

    while True:
        client.send(b"Client 1: hi\n")
        time.sleep(1)

    client.close()


0 commentaires

0
votes
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
#kate: syntax Python ;

# use them like so:

import          socket,               os , time
parent, child = socket.socketpair()

#child.close() # bad fdesc

pid           =                       os.fork()
if pid:
    #time.sleep(0.3)
    #child.close()
    print 'in   parent, sending    message'
    p =         parent.sendall('ping p')
    response1 = parent.recv(444)
    print      'response from child         :', response1
    p =         parent.close()

else:
    #time.sleep(0.7)
    #parent.close()

    print  'in child, waiting for message'
    message1 = child.recv(333)
    print  'message from parent         :', message1

    child.sendall('päng c')
    child.close()

#print "Ende" , pid
#print parent # , child
#print type(pid) , " -- " , type(child)

0 commentaires