Niedawno udało mi się stworzyć gniazda na moim komputerze i moim Raspberry Pi, aby umożliwić komunikację między obydwoma urządzeniami. Obecnie klient może automatycznie wysyłać wiadomości na serwer. Zastanawiam się, czy można zmodyfikować skrypty do wysyłania pakietów danych tcp zamiast czysto tekstowych, ponieważ bardzo chciałbym kontrolować raspberry pi używając mojego komputera w przyszłości, bez potrzeby ssh/etc.Wysyłanie/odbieranie pakietów z gniazdami TCP
Przyjrzałem się kilku przykładom, ale ponieważ nie mam dużego doświadczenia w pisaniu własnych skryptów/kodów, nie jestem pewien, jak to zrobić. Byłbym wdzięczny, gdyby ktoś mógł poprowadzić mnie we właściwym kierunku z wyjaśnieniami i przykładami, jeśli to możliwe.
Zresztą tutaj jest skrypt serwer/klient biegnę w tej chwili:
Klient:
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()
Serwer:
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()
Czytałem gniazda RAW oraz sposób wysyłania/odbierania pakietów RAW w TCP/IP i wymagałoby ręcznego określenia nagłówków tcp i ip w skrypcie. Czy byłby to lepszy sposób wysyłania pakietów do raspberry pi, aby kontrolować niektóre z jego funkcji? Niestety, jak wspomniałem, nie mam dużego doświadczenia z gniazdkami i pakietami. Skrypty, które używam, są standardowymi gniazdami, a ładunek "wiadomość" jest przesyłany przez TCP, czy możliwe jest zmodyfikowanie części skryptu w celu wysyłania pakietów (nie jako danych tekstowych) do wykonania pracy? – intensified
Czy obsługa gniazda socket.error byłaby jedynym sposobem sprawdzenia błędów w wysyłanych danych? czy jest jakiś inny sposób, w jaki moglibyśmy dokonać sprawdzenia błędu, na przykład gdy dane otrzymane na serwerze, wykonaliby kontrolę nadmiarową, aby upewnić się, że nie ma danych utraconych podczas transmisji? – intensified