2013-07-06 20 views
5

Recentemente, sono riuscito a creare socket sul mio PC e sul mio Raspberry Pi per abilitare la comunicazione tra entrambi i dispositivi. Attualmente, il client è in grado di inviare automaticamente messaggi al server. Mi chiedevo se fosse possibile modificare gli script per inviare pacchetti di dati tcp invece di messaggi puramente testuali, dato che mi piacerebbe molto controllare il raspberry pi usando il mio PC in futuro senza avere la necessità di ssh/etc.Pacchetti di invio/ricezione con socket TCP

Ho esaminato alcuni esempi, ma poiché non ho molta esperienza nello scrivere i miei script/codici, non sono molto sicuro su come procedere. Apprezzerei se qualcuno potesse guidarmi nella giusta direzione con la spiegazione e alcuni esempi se possibile.

Comunque qui è lo script server/client sono in esecuzione in questo momento:

Cliente:

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() 

Server:

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() 

risposta

0

Sei già inviando pacchetti di dati - quelli capita che i pacchetti contengano dati di testo al momento. Prova a guardare in pickle nelle librerie standard e in pyro.

+0

Stavo leggendo le prese RAW e come invia/ricevono pacchetti RAW in TCP/IP e richiederebbe che le intestazioni tcp e ip vengano specificate manualmente nello script. Sarebbe un modo migliore per inviare i pacchetti al raspberry pi per controllare alcune delle sue funzioni? Scusa, come detto, non ho molta esperienza con socket e pacchetti. Gli script che sto utilizzando sono socket standard e il payload "message" viene trasmesso via TCP, è possibile modificare parti dello script per inviare pacchetti (non come dati di testo) invece di eseguire il lavoro? – intensified

+0

Inoltre, la gestione socket.error sarebbe l'unico modo per verificare la presenza di errori nei dati inviati? o c'è un altro modo in cui potremmo fare il controllo degli errori, ad esempio quando i dati ricevuti sul server eseguiranno un controllo di ridondanza per garantire che non ci siano dati persi durante la trasmissione? – intensified

3

socket.socket(socket.AF_INET, socket.SOCK_STREAM) crea già una connessione che fornisce un flusso affidabile di byte tra due macchine. Questo usa TCP, che è sopra IP e Ethernet. Gli ultimi due sono basati sui pacchetti, mentre TCP crea un flusso di byte continui su di esso. Aggiunge anche alcuni errori di controllo e correzione degli errori, quindi è abbastanza affidabile.

Sinceramente non capisco cosa vuoi ottenere con ciò che chiami "invia pacchetti". Quello che non si vuole fare è creare un'implementazione del TCP da soli, poiché si tratta di un'attività non banale, quindi l'invio di pacchetti RAW è fuori. In generale, anche l'uso del TCP è già relativamente di basso livello e dovrebbe essere evitato a meno che non sia realmente necessario.

Utilizzo ad es. ZeroMQ si ottiene un'interfaccia basata su messaggi che esegue tutta la trasmissione per te. Lo fa su TCP (o altri trasporti) e aggiunge più correzione degli errori per es. disconnette. Lì, hai anche qualcosa come "pacchetti", ma quelli sono indipendenti da quanti pacchetti TCP o IP sono stati richiesti per inviarlo sotto. Se non si desidera implementare un protocollo specifico, suggerirei di utilizzare questo framework anziché i socket TCP di livello inferiore.

Un'altra semplice alternativa è utilizzare HTTP, per cui esiste anche un codice esistente in Python. Il rovescio della medaglia è che è sempre un lato che inizia una comunicazione e l'altra parte solo le risposte. Se vuoi un qualche tipo di notifica attiva, devi o sondare o usare hack come ritardare una risposta.

Problemi correlati