J'utilise le module socket de Python 3.7 (cela n'a pas d'importance, car j'ai essayé d'activer une version Python différente à partir de différents venv).

Le problème est que j'ai créé une connexion TCP en écoutant sur le port 65432, un nombre arbitraire que j'ai sélectionné pour cette démonstration simple.

server.py ressemble à ceci:

import socket

HOST = '127.0.0.1' # Standard loopback interface address (localhost)
PORT = 65432 # Non-privileged ports are > 1024

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.bind((HOST, PORT))
    s.listen() 
    conn, addr = s.accept() 
    with conn:
        print('Connected by', addr)
        while True:
            data = conn.recv(1024)
            if not data:
                break
            conn.sendall(data)

client.py est relativement simple car il établit une connexion avec 127.0.0.1:65432.

import socket

HOST = '127.0.0.1' # The server's hostname or IP address
PORT = 65432 # Port used by the server

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.connect((HOST, PORT))
    # Send its message and then read the server's reply and prints it
    s.sendall(b'Hello, world')
    data = s.recv(1024)

print('Received', repr(data))

Exécution de server.py pour ouvrir le port 65432 pour l'écoute (dans la première console), puis exécution de client.py pour envoyer un simple message "hello world" (dans une deuxième console). C'est ce qui a été imprimé sur la première console:

Connected by ('127.0.0.1', 56051)

Jusqu'ici tout va bien. Le port 56051 se connecte au port 65432, non? Non.

J'exécute netstat -am (utilitaire d'outil de commande pour voir l'état des sockets sur la machine hôte) et trouve ceci:

Active Internet connections (including servers)
Proto Recv-Q Send-Q  Local Address          Foreign Address        (state)    
tcp4       0      0  127.0.0.1.51495        *.*                    LISTEN 

Au lieu de 127.0.0.1.65432 comme adresse locale , il utilise à la place le port 51495.

Faire une autre vérification de vérification, cette fois en tirant lsof -i -n:

COMMAND     PID     FD   TYPE             DEVICE SIZE/OFF NODE NAME
Code\x20H 51214    37u  IPv4 0x1af15eb424ba89f3      0t0  TCP 127.0.0.1:51495 (LISTEN)

Les deux vérifications ont confirmé que le port 51495 est utilisé au lieu de 65432 comme spécifié dans mes scripts server.py et client.py. Des pistes ou des conseils? Merci d'avance!

0
onlyphantom 17 mars 2019 à 09:44

2 réponses

Meilleure réponse

Comme l'a souligné @ottomeister, le nom du processus a été le premier cadeau. Le nom du processus aurait dû être Python mais il montrait VS Code à la place, ce qui indique que le port 51495 est ouvert par le processus VS Code et n'a rien à voir avec notre code de module de socket.

La façon dont le gestionnaire de contexte a été configuré signifie que la connexion sera fermée au moment où la dernière ligne (dans ce cas, socket.sendall()) est exécutée. Le socket serveur n'est donc plus actif.

J'exécute netstat après la connexion du socket client, à ce stade, le port du serveur est fermé.

Lorsque je surveille l'état des ports alors que le port du serveur est ouvert (avant que le socket client ne s'y connecte), alors 65432 est suffisamment visible. Ceci est confirmé dans netstat, lsof et aussi nmap. Une simple déclaration d'impression après la connexion réussie confirmera également que le port du serveur utilise en fait le numéro de port spécifié, qui est 65432.

Désolé pour la gêne occasionnée et encore une fois beaucoup de remerciement à Ottomeister pour la première fois.

0
onlyphantom 18 mars 2019 à 07:43

65432 est le numéro de port de votre socket serveur, pas votre socket client. Comme l'extrémité client n'est pas associée à un numéro de port spécifique, elle sera allouée dynamiquement avec le numéro de port, chaque fois que vous exécutez le code client. D'après ce que j'ai compris, vous avez mentionné -

Connected by ('127.0.0.1', 56051)

Est affiché sur la première console qui est votre console de serveur. donc ce numéro de port est le numéro de port du socket client. pas le socket du serveur.

Dans le code du serveur que vous utilisez, s.accept (), cette fonction renvoie l'ID temporaire de connexion et l'adresse du client qui a fait la demande. même chose que vous essayez d'imprimer dans le code.

0
Anshu Pandey 17 mars 2019 à 07:41