Send/receive Packets with TCP sockets
Solution 1
socket.socket(socket.AF_INET, socket.SOCK_STREAM)
already creates a connection that provides a reliable stream of bytes between two machines. This uses TCP, which is on top of IP and Ethernet. The latter two are package-based, while TCP creates a stream of continuous bytes on top of it. It also adds some error checking and error correction, so it is pretty reliable.
I honestly don't understand what you want to achieve with what you call "send packets". What you don't want to do is to create an implementation of TCP yourself, as that's a non-trivial task, so sending RAW packets is out. In general, even using TCP is already relatively low-level and should be avoided unless really necessary.
Using e.g. ZeroMQ you get a message-based interface that does all the transmission for you. It does so on top of TCP (or other transports) and adds more error correction for e.g. disconnects. There, you also have something like "packets", but those are independent of how many TCP or IP packets were required to send it underneath. If you don't want to implement a specific protocol, I'd suggest you use this framework instead of lowlevel TCP sockets.
Another simple alternative is to use HTTP, for which there is also existing code in Python. The downside is that it is always one side that initiates some communication and the other side only replies. If you want some kind of active notification, you either have to poll or use hacks like delaying an answer.
Solution 2
You are already sending data packets - those packets juts happen to contain text data at the moment. Try looking into pickle in the standard libraries and into pyro.
intensified
Updated on November 29, 2020Comments
-
intensified over 3 years
Recently, I managed to create sockets on my PC and my Raspberry Pi to enable communication between both devices. Currently, the client is able to automatically send messages to the server. I was wondering, if it is possible to modify the scripts to send tcp data packets instead of purely text messages, as I would very much like to control the raspberry pi using my PC in the future without having the need to ssh/etc.
I've looked at some examples, but as I don't have much experience in writing my own scripts/codes, I'm not very sure how to go about doing this. I would appreciate if someone could guide me in the right direction with explanation and some examples if possible.
Anyway here is the server/client script I'm running at the moment:
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()
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()