Pages : 1
#1 Le 04/07/2013, à 08:36
- Shanx
Python : écoute d’un port TCP
Bonjour à tous
je voudrais faire un programme en python qui joue un rôle de serveur : il écoute un port TCP (dans mes exemples le port 81), et quand il reçois quelque chose il répond sur le port 234. J’ai récupéré des morceaux de codes sur internet, et j’arrive à faire communiquer 2 programmes qui sont lancés sur la même machine. Par contre, impossible de faire ça entre deux stations différentes situées dans le même réseau local.
Le serveur a pour adresse 192.168.0.70, et l’ordi avec lequel j’essaie de communiquer 192.168.0.54 (mais normalement on ne se sert pas de cette adresse IP). Le code serveur.py est le suivant :
#!/usr/bin/python3
#coding: utf-8
import socket
import time
Connecteur = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
Hote = '192.168.0.70' #IP du serveur
Port = 81
Connecteur.bind((Hote,Port))
print ("Le programme est a l'ecoute d'une eventuelle discussion, vous en serez averti.")
Connecteur.listen(2)
client, adresse = Connecteur.accept()
print ("L'ordinateur",adresse,"veut discuter ! J'attends son message.")
# Creation du connecteur de reponse
Reponse = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
print("test1")
Portreponse = 234
print("test2")
time.sleep(2) # Temporisation necessaire, sinon echec même en local
Reponse.connect((Hote,Portreponse))
print ("Note : je me suis connecte a",adresse,"pour lui repondre")
while 1:
Message = str(client.recv(255),'mac_roman')
if not Message:
break
print ("\nMessage : ",Message,"\a" + "\n\nVotre reponse :")
msgR = bytes(input('>> '), 'mac_roman')
Reponse.send(msgR) # envoi.
client.close()
Et client.py :
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import socket
import time
Discuter = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
Hote = '192.168.0.70'
Port = 81
Port_de_reponse = 234
Discuter.connect((Hote,Port))
print("test1")
Reponse = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
print("test2")
Reponse.bind((Hote,Port_de_reponse))
Reponse.listen(1)
print("test3")
client, adresse = Reponse.accept()
print ("L'adresse",adresse," vous a entendu et attend votre message.")
while 1:
msg = bytes(input('>> '), 'mac_roman')
Discuter.send(msg)
print ("Attente de la reponse...")
reponseaumessage = str(client.recv(255),'mac_roman')
if not reponseaumessage:
break
print ("\n",adresse,":",reponseaumessage,"\a\n")
client.close()
Et les erreurs que j’ai sont les suivantes :
sur le serveur :
$ sudo ./serveur.py
Le programme est a l'ecoute d'une eventuelle discussion, vous en serez averti.
L'ordinateur ('192.168.0.54', 57185) veut discuter ! J'attends son message.
test1
test2
Traceback (most recent call last):
File "./ecoute.py", line 21, in <module>
Reponse.connect((Hote,Portreponse))
socket.error: [Errno 111] Connection refused
sur le client :
$ sudo client.py
test1
test2
Traceback (most recent call last):
File "python/discussion.py", line 14, in <module>
Reponse.bind((Hote,Port_de_reponse))
OSError: [Errno 99] Cannot assign requested address
Le message d’erreur apparait d’abord sur le client, mais je ne sais pas si c’est parce que c’est lui qui plante ou si c’est à cause de la temporisation sur le serveur.
J’ai pensé que les ports n’étaient pas ouverts, donc j’ai fait mumuse avec iptables et j’ai mis les même règles sur les deux machines :
$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- anywhere anywhere tcp dpt:234
ACCEPT tcp -- anywhere anywhere tcp dpt:81
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- anywhere anywhere tcp dpt:234
ACCEPT tcp -- anywhere anywhere tcp dpt:81
Mais ça n’a rien changé. J’avoue que je commence à être perdu… Quelqu’un a une suggestion ?
Mes randos : grande traversées des Alpes, de l'Islande, de la Corse, du Japon (en vélo), etc.
Traversée des États-Unis à pied
Hors ligne
#2 Le 04/07/2013, à 09:11
- grim7reaper
Re : Python : écoute d’un port TCP
Chezmoiçamarche.
Du moins quand je lance les deux en root (au passage, je trouve que c’est une mauvaise idée de passer par des ports réservés).
Par contre j’ai testé en local (127.0.0.70).
Bon du coup, à priori le problème ne devrait pas venir du code en lui-même.
sudo ./server.py
Le programme est a l'ecoute d'une eventuelle discussion, vous en serez averti.
L'ordinateur ('127.0.0.1', 36293) veut discuter ! J'attends son message.
test1
test2
Note : je me suis connecte a ('127.0.0.1', 36293) pour lui repondre
Message : toto
Votre reponse :
>> titi
Message : foo
Votre reponse :
>> bar
sudo ./client.py
test1
test2
test3
L'adresse ('127.0.0.1', 32960) vous a entendu et attend votre message.
>> toto
Attente de la reponse...
('127.0.0.1', 32960) : titi
>> foo
Attente de la reponse...
('127.0.0.1', 32960) : bar
>>
Sinon, ton sleep me semble inutile (du moins en local il ne sert à rien, ça fonctionne très bien sans)
Dernière modification par grim7reaper (Le 04/07/2013, à 09:15)
Hors ligne
#3 Le 04/07/2013, à 09:41
- Jules Petibidon
Re : Python : écoute d’un port TCP
+1 quant aux ports connus.
Sinon ça sert à quoi d'utiliser des ports différents pour la requête et la réponse ?
Hors ligne
#4 Le 04/07/2013, à 09:56
- Shanx
Re : Python : écoute d’un port TCP
@grim : oui, ça marche en local, c’est ce que j’avais dit :
j’arrive à faire communiquer 2 programmes qui sont lancés sur la même machine. Par contre, impossible de faire ça entre deux stations différentes situées dans le même réseau local. hmm
Du coup on est d’accord que le problème se trouve plutôt sur le réseau…
Le sleep est nécessaire, parce que le serveur est un raspberry (donc peu puissant), et si je ne le met pas le programme plante (je pense qu’il n’a pas le temps d’ouvrir un port ou une histoire du genre).
Je ne vois pas pourquoi c’est une mauvaise idée de passer par des ports réservés… D’ailleurs, je ne vois pas comment on peut faire sans ça.
@Jules : j’ai essayé de mettre les mêmes ports, ça ne fonctionne pas. Je vais d’abord essayer de faire communiquer les deux stations, et une fois que ce era fait je verrais s’il y a des trucs à améliorer.
Mes randos : grande traversées des Alpes, de l'Islande, de la Corse, du Japon (en vélo), etc.
Traversée des États-Unis à pied
Hors ligne
#5 Le 04/07/2013, à 10:08
- grim7reaper
Re : Python : écoute d’un port TCP
Du coup on est d’accord que le problème se trouve plutôt sur le réseau…
Pas sûr, mais en tout cas c’est le bind qui foire (et comme le bind foire, ensuite le connect du serveur foire aussi)
Le sleep est nécessaire, parce que le serveur est un raspberry (donc peu puissant), et si je ne le met pas le programme plante (je pense qu’il n’a pas le temps d’ouvrir un port ou une histoire du genre).
Ok, mais dans ce cas ton commentaire est faux (enfin, imprécis au point où il en devient factuellement faux).
Je ne vois pas pourquoi c’est une mauvaise idée de passer par des ports réservés… D’ailleurs, je ne vois pas comment on peut faire sans ça.
Et bien parce qu’il sont réservé, c’est pas pour les appli’ de chez mémé.
Et c’est très facile de faire sans : il suffit de prendre un port > 1023 (seul les 1024 premiers sont réservés). En plus, tu n’auras plus besoin de lancer tes programmes en root comme ça.
Édit : d’ailleurs au passage, le bind dans ton client me chiffone. Un client est pas censé faire de bind…
Dernière modification par grim7reaper (Le 04/07/2013, à 10:20)
Hors ligne
#6 Le 04/07/2013, à 10:19
- Shanx
Re : Python : écoute d’un port TCP
Ah oui, c’est ça les ports réservés… En effet, j’avais prévu de prendre d’autres ports pour la suite. C’est juste que comme ça ne fonctionnait pas, j’ai tenté avec des ports moins exotiques (quand on est désespéré…).
Bon, du coup le bind ne fonctionne pas. Quelqu’un a une proposition de solution ?
Mes randos : grande traversées des Alpes, de l'Islande, de la Corse, du Japon (en vélo), etc.
Traversée des États-Unis à pied
Hors ligne
#7 Le 04/07/2013, à 10:31
- grim7reaper
Re : Python : écoute d’un port TCP
Ouais, le bind client est bel et bien inutile.
Essaye ça :
* serveur
#!/usr/bin/python3
#coding: utf-8
import socket
import time
HOTE = '127.0.0.70' #IP du serveur
PORT = 8100
serv_soc = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
serv_soc.bind((HOTE, PORT))
serv_soc.listen(2)
print ("Le programme est a l'ecoute d'une eventuelle discussion, vous en serez averti.")
clt_soc, address = serv_soc.accept()
print ("L'ordinateur", address, "veut discuter ! J'attends son message.")
while 1:
msg = str(clt_soc.recv(255),'mac_roman')
if not msg:
break
print ('\nMessage : ', msg ,'\a' + '\n\nVotre reponse :')
msgR = bytes(input('>> '), 'mac_roman')
clt_soc.send(msgR)
clt_soc.close()
serv_soc.close()
* client
#!/usr/bin/python3
#coding: utf-8
import socket
import time
HOTE = '127.0.0.70'
PORT = 8100
soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
soc.connect((HOTE, PORT))
while 1:
msg = bytes(input('>> '), 'mac_roman')
soc.send(msg)
response = str(soc.recv(255),'mac_roman')
if not response:
break
print ('\n','response:',response,'\a\n')
soc.close()
Va peut-être falloir que tu mettes ton sleep par contre.
Et puis changer les IP.
Dernière modification par grim7reaper (Le 04/07/2013, à 10:37)
Hors ligne
#8 Le 04/07/2013, à 10:44
- Shanx
Re : Python : écoute d’un port TCP
serveur.py :
#!/usr /bin/python3
#coding: utf-8
import socket
import time
HOTE = '127.0.0.1' #IP du serveur
PORT = 8100
serv_soc = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
serv_soc.bind((HOTE, PORT))
serv_soc.listen(2)
print ("Le programme est a l'ecoute d'une eventuelle discussion, vous en serez averti.")
clt_soc, address = serv_soc.accept()
print ("L'ordinateur", address, "veut discuter ! J'attends son message.")
while 1:
msg = str(clt_soc.recv(255),'mac_roman')
if not msg:
break
print ("\nMessage : ", msg ,"\a" + "\n\nVotre reponse :")
msgR = bytes(input('>> '), 'mac_roman')
clt_soc.send(msgR)
clt_soc.close()
serv_soc.close()
client.py :
#!/usr/bin/python3
#coding: utf-8
import socket
import time
HOTE = '192.168.0.70'
PORT = 8100
soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
soc.connect((HOTE, PORT))
while 1:
msg = bytes(input('>> '), 'mac_roman')
soc.send(msg)
response = str(soc.recv(255),'mac_roman')
if not response:
break
print ("\n",adresse,":",response,"\a\n")
soc.close()
Le serveur se lance bien, mais pas le client :
$ ./client.py
Traceback (most recent call last):
File "./client.py", line 10, in <module>
soc.connect((HOTE, PORT))
ConnectionRefusedError: [Errno 111] Connection refused
Le serveur est lui imperturbable, il ne semble rien recevoir.
Pourtant j’ai bien rajouté une entrée dans iptables pour autoriser le trafic entrant sur le port 8100 sur le serveur.
Mes randos : grande traversées des Alpes, de l'Islande, de la Corse, du Japon (en vélo), etc.
Traversée des États-Unis à pied
Hors ligne
#9 Le 04/07/2013, à 10:51
- tiramiseb
Re : Python : écoute d’un port TCP
Salut,
Je te propose de commencer par voir si c'est lié à ton programme ou au réseau (ou à autre chose, qui sait).
Au plus simple, je te dirais d'utiliser nc :
1/ sur le serveur :
nc -l -p 8100
2/ sur le client :
nc 192.168.0.70 8100
3/ sur le client, taper n'importe quoi :
toto
puis entrée, la chaîne devrait apparaître sur le serveur :
toto
Si à l'étape 2 ça déconne (ou éventuellement à la 3), alors c'est probablement un problème de réseau et tu peux faire tes tests avec nc de cette manière jusqu'à ce que ça marche. Ensuite tu retourneras sur ton programme en Python.
Sébastien Maccagnoni - https://www.maccagnoni.eu - https://www.domotego.com
Hors ligne
#10 Le 04/07/2013, à 10:55
- Shanx
Re : Python : écoute d’un port TCP
J’aurais du penser à faire ça.
Ça fonctionne parfaitement. Du coup, ça vient bien du programme. Je ne sais pas si c’est une bonne nouvelle ou pas.
Mes randos : grande traversées des Alpes, de l'Islande, de la Corse, du Japon (en vélo), etc.
Traversée des États-Unis à pied
Hors ligne
#11 Le 04/07/2013, à 10:55
- tiramiseb
Re : Python : écoute d’un port TCP
Par ailleurs, côté serveur je te conseille d'utiliser le module socketserver, plus haut niveau que socket...
http://docs.python.org/3/library/socket … er-example
(peut-être que ça résoudrait ton problème avec le "sleep" aussi... Mais je ne peux pas être affirmatif, je n'ai que survolé ton code)
Sébastien Maccagnoni - https://www.maccagnoni.eu - https://www.domotego.com
Hors ligne
#12 Le 04/07/2013, à 10:58
- tiramiseb
Re : Python : écoute d’un port TCP
« quand il reçois quelque chose il répond sur le port 234 » : je ne comprends pas ce que tu veux faire.
tu veux que, quand le serveur reçoit une requête, il initie une connexion vers le port 234 (ou autre) du client ?
Dans ce cas, ton client serait aussi un serveur...
Sébastien Maccagnoni - https://www.maccagnoni.eu - https://www.domotego.com
Hors ligne
#13 Le 04/07/2013, à 11:18
- Jules Petibidon
Re : Python : écoute d’un port TCP
A priori dans serveur.py :
HOTE = '127.0.0.1' #IP du serveur
Fait que le serveur ne répond qu'à lui même et refuse le reste
donc
HOTE = '192.168.0.70' #IP publique du serveur
ou encore
HOTE = '' #Répond à n'importe quoi d'après la doc
Hors ligne
#14 Le 04/07/2013, à 11:22
- tiramiseb
Re : Python : écoute d’un port TCP
C't'œil de lynx Jules !
Très bien vu, pour le code en #8.
Bon par contre le code en #1 a bien "Hote" en "192.168.0.70"...
Dernière modification par tiramiseb (Le 04/07/2013, à 11:22)
Sébastien Maccagnoni - https://www.maccagnoni.eu - https://www.domotego.com
Hors ligne
#15 Le 04/07/2013, à 11:31
- Shanx
Re : Python : écoute d’un port TCP
Bravo Jules
J’ai mis HOTE = '', et ça fonctionne (modulo une petite correction du code de grim). Maintenant le serveur écoute, et peut même répondre au client.
À terme, le client enverra des données au serveur, qui les stockera dans une bdd et enverra un acquittement. Vous venez de me tirer une sacrée épine du pied.
Mes randos : grande traversées des Alpes, de l'Islande, de la Corse, du Japon (en vélo), etc.
Traversée des États-Unis à pied
Hors ligne
#16 Le 04/07/2013, à 11:31
- tiramiseb
Re : Python : écoute d’un port TCP
Sinon, sérieusement, utilise socketserver, ça va te simplifier la vie...
Sébastien Maccagnoni - https://www.maccagnoni.eu - https://www.domotego.com
Hors ligne
#17 Le 04/07/2013, à 11:33
- Shanx
Re : Python : écoute d’un port TCP
Ça va m’apporter quoi ?
Mes randos : grande traversées des Alpes, de l'Islande, de la Corse, du Japon (en vélo), etc.
Traversée des États-Unis à pied
Hors ligne
#18 Le 04/07/2013, à 11:41
- tiramiseb
Re : Python : écoute d’un port TCP
Bah y'a rien qu'à voir l'exemple de code, c'est vachement plus simple. En plus c'est orienté objet.
Et puis ton code actuel, peut-il accepter des connexions de plusieurs clients ? J'ai l'impression qu'il est bloquant sur un seul client (mais je peux me tromper, je n'ai pas essayé).
Ton serveur en #8 devient :
#!/usr/bin/env python3
#coding: utf-8
HOTE = ''
PORT = 8100
import socketserver
class MonHandlerTCP(socketserver.BaseRequestHandler):
def handle(self):
print ("\nMessage : {}\a\n\nVotre reponse :".format(str(self.request.recv(1024).strip(), 'mac_roman')))
self.request.sendall(bytes(input('>> '), 'mac_roman'))
if __name__ == "__main__":
socketserver.TCPServer((HOTE, PORT), MonHandlerTCP).serve_forever()
Dernière modification par tiramiseb (Le 04/07/2013, à 11:43)
Sébastien Maccagnoni - https://www.maccagnoni.eu - https://www.domotego.com
Hors ligne
#19 Le 04/07/2013, à 11:45
- tiramiseb
Re : Python : écoute d’un port TCP
Par ailleurs, pourquoi "mac_roman" ? Tu ne fais pas tout en utf-8 ?
Moi mon terminal il est full UTF-8 en tout cas.
Sébastien Maccagnoni - https://www.maccagnoni.eu - https://www.domotego.com
Hors ligne
Pages : 1