Envoyer/recevoir des Paquets avec les sockets TCP
Récemment, j'ai réussi à créer des sockets sur mon PC et mon Raspberry Pi pour permettre la communication entre les deux appareils. Actuellement, le client est capable d'envoyer automatiquement des messages sur le serveur. Je me demandais, si il est possible de modifier les scripts pour envoyer des paquets de données tcp au lieu de purement messages texte, comme je le voudrais bien pour contrôler le raspberry pi à l'aide de mon PC à l'avenir sans avoir le besoin de ssh/etc.
J'ai regardé quelques exemples, mais comme je n'ai pas beaucoup d'expérience dans l'écriture de mes propres scripts/codes, je ne suis pas très sûr de savoir comment aller à ce sujet. Je vous serais reconnaissant si quelqu'un pouvait me guider dans la bonne direction avec des explications et des exemples si possible.
De toute façon, ici, c'est le client/serveur de script que je suis en cours d'exécution à l'instant:
Client:
import socket
import sys
import struct
import time
#main function
if __name__ == "__main__":
if(len(sys.argv) < 2) :
print 'Usage : python client.py hostname'
sys.exit()
host = sys.argv[1]
port = 8888
#create an INET, STREAMing socket
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error:
print 'Failed to create socket'
sys.exit()
print 'Socket Created'
try:
remote_ip = socket.gethostbyname( host )
s.connect((host, port))
except socket.gaierror:
print 'Hostname could not be resolved. Exiting'
sys.exit()
print 'Socket Connected to ' + host + ' on ip ' + remote_ip
#Send some data to remote server
message = "Test"
try :
#Set the whole string
while True:
s.send(message)
print 'Message sent successfully'
time.sleep(1)
print 'Sending...'
except socket.error:
#Send failed
print 'Send failed'
sys.exit()
def recv_timeout(the_socket,timeout=2):
#make socket non blocking
the_socket.setblocking(0)
#total data partwise in an array
total_data=[];
data='';
#beginning time
begin=time.time()
while 1:
#if you got some data, then break after timeout
if total_data and time.time()-begin > timeout:
break
#if you got no data at all, wait a little longer, twice the timeout
elif time.time()-begin > timeout*2:
break
#recv something
try:
data = the_socket.recv(8192)
if data:
total_data.append(data)
#change the beginning time for measurement
begin=time.time()
else:
#sleep for sometime to indicate a gap
time.sleep(0.1)
except:
pass
#join all parts to make final string
return ''.join(total_data)
#get reply and print
print recv_timeout(s)
s.close()
Serveur:
import socket
import sys
from thread import *
HOST = '' # Symbolic name meaning all available interfaces
PORT = 8888
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'
try:
s.bind((HOST, PORT))
except socket.error , msg:
print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
sys.exit()
print 'Socket bind complete'
s.listen(10)
print 'Socket now listening'
#Function for handling connections
def clientthread(conn):
#Sending message to connected client
conn.send('Welcome to the server. Receving Data...\n') #send only takes string
#infinite loop so that function do not terminate and thread do not end.
while True:
#Receiving from client
data = conn.recv(1024)
reply = 'Message Received at the server!\n'
print data
if not data:
break
conn.sendall(reply)
conn.close()
#now keep talking with the client
while 1:
#wait to accept a connection
conn, addr = s.accept()
print 'Connected with ' + addr[0] + ':' + str(addr[1])
#start new thread
start_new_thread(clientthread ,(conn,))
s.close()
OriginalL'auteur intensified | 2013-07-06
Vous devez vous connecter pour publier un commentaire.
socket.socket(socket.AF_INET, socket.SOCK_STREAM)
déjà crée une connexion qui fournit une source fiable d'octets entre deux machines. Il utilise le protocole TCP, qui est au-dessus d'IP et Ethernet. Les deux derniers sont basées sur le package, alors que le protocole TCP crée un flux continu d'octets sur le dessus de cela. Il ajoute également un contrôle d'erreur et de correction d'erreur, de sorte qu'il est assez fiable.Honnêtement, je ne comprends pas ce que vous voulez atteindre avec ce que vous appelez "envoyer des paquets". Ce que vous ne voulez pas faire est de créer une mise en œuvre de TCP-vous, car c'est une tâche non triviale, donc envoyer les paquets. En général, même en utilisant le protocole TCP est déjà relativement faible et doit être évitée sauf si vraiment nécessaire.
Par exemple à l'aide ZeroMQ, vous obtenez un message basé sur l'interface qui est de la transmission pour vous. Il le fait sur le dessus de TCP (ou d'autres moyens de transport), et ajoute plus de la correction d'erreur pour par exemple se déconnecte. Là, vous avez aussi quelque chose comme "paquets", mais celles-ci sont indépendantes de la façon dont beaucoup de TCP ou IP des paquets ont été nécessaires pour l'envoyer en dessous. Si vous ne voulez pas mettre en œuvre un protocole spécifique, je vous suggérons d'utiliser ce cadre au lieu de bas niveau sockets TCP.
Une autre alternative simple est d'utiliser le protocole HTTP, pour lesquels il est aussi existante code en Python. L'inconvénient est qu'il est toujours un côté qui initie la communication et de l'autre côté uniquement les réponses. Si vous voulez une sorte de notification actif, soit vous avez de sondage ou d'utiliser des hacks comme retarder une réponse.
OriginalL'auteur Ulrich Eckhardt
Vous êtes déjà l'envoi de paquets de données - ces paquets s'avance contiennent des données de texte pour le moment. Essayez de regarder dans cornichon dans les bibliothèques standard et en pyro.
Aussi, serait le support.erreur de manipulation être la seule façon de vérifier les erreurs dans les données envoyées? ou est-il un autre moyen nous pourrions faire la vérification des erreurs, par exemple lorsque les données reçues au niveau du serveur, il serait d'effectuer un contrôle de redondance pour s'assurer qu'il n'y a pas de perte de données lors de la transmission?
OriginalL'auteur Steve Barnes