Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.6k views
in Technique[技术] by (71.8m points)

How to make a fast continuous stream of data with socket on Python?

I am writing a code where an arduino reads data from an accelerometer, passes it to a python script and then that computer running python sends the data to another computer over a socket conneciton. I have written code which can send and recieve one message at a time, slowly, but as soon as I do it bascially as fast as I can (about 100Hz) then the server side only prints the first message, but no more.

Here is the code for my server side:

import socket


class server:

    def __init__(self, PORT=9077, MAX_CONNECTIONS=1000, BUFF_SIZE=1024):
        self.s = socket.socket()
        self.HOST = socket.gethostbyname(socket.gethostname())
        self.PORT = PORT
        self.MAX_CONNECTIONS = MAX_CONNECTIONS
        self.BUFF_SIZE = BUFF_SIZE
        self.s.bind((self.HOST, self.PORT))
        self.s.listen(self.MAX_CONNECTIONS)
        self.recievingData = False
        
        print("Starting a server")
        print("IP: " + str(self.HOST))
        print("Port: " + str(self.PORT))

    def recieveData(self):
        self.recievingData = True
        while self.recievingData:
            print("Waiting for data")
            c, addr = self.s.accept()
            print(addr)
            data = b''
            part = c.recv(self.BUFF_SIZE)
            data += part
            while len(part) > self.BUFF_SIZE:
                # print("looping")
                part = c.recv(self.BUFF_SIZE)
                print(len(part))
                data += part
            print(data)
            c.close()

    def stopRecieving(self):
        self.revievingData = False
            
    
    new_server = server()
    new_server.recieveData()

and the client side:

class client:
    
    def __init__(self, HOST="192.168.0.51", PORT=9077):
        self.s = socket.socket()
        self.HOST = HOST
        self.PORT = PORT
        self.s.connect((self.HOST, self.PORT))

    def send_message(self, message):
        message = message.encode()
        sent = self.s.sendall(message)
        print(sent)

and I basically just call send_message every time there is new data to send.

Is there a way to increase the speed at which the server can recieve messages from the same client? Do I need to create multiple threads for recieving data?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

My solution to this was using DTP protocol, where you send messages without checking if the data has been recieved. This is achieved using socket.socket(type=SOCK_DGRAM) on the client and server side and using self.s.recvfrom(self.BUFF_SIZE) for recieving data from a client and self.s.sendto(str(message).encode(), (host, port)) for sending data. This way, there is no handshake between the client and the server and it runs much faster.

You just need some error checking from your input data.

For reference, this is my full updated code:

import socket
from socket import SOCK_DGRAM, SO_REUSEADDR
import numpy as np
import threading

class client:
    
    def __init__(self, HOST="192.168.0.51", PORT=9077):
        self.s = socket.socket(type=SOCK_DGRAM)
        self.HOST = HOST
        self.PORT = PORT

    def send_message(self, message):
        self.s.sendto(str(message).encode(), (host, port))

class server:

    def __init__(self, PORT=9077, BUFF_SIZE=1024):
        self.s = socket.socket(type=SOCK_DGRAM)
        self.HOST = socket.gethostbyname(socket.gethostname())
        self.PORT = PORT
        self.MAX_CONNECTIONS = MAX_CONNECTIONS
        self.BUFF_SIZE = BUFF_SIZE
        self.s.bind((self.HOST, self.PORT))
        # self.s.listen(self.MAX_CONNECTIONS)
        self.recievingData = False
        self.recievedData = np.zeros((1,4))
        
        self.thread = threading.Thread(target=self.recieveData)
        self.thread.start()
        # self.s.setblocking(0)
        self.startRecieving()
        
        print("Starting a server")
        print("IP: " + str(self.HOST))
        print("Port: " + str(self.PORT))

    def startRecieving(self):
        self.recievingData = True
        self.recievedData = np.zeros((1,4))
        self.thread = threading.Thread(target=self.recieveData)
        self.thread.start()
        print("Started reading data")
    
    def stopRecieving(self):
        self.recievingData = False
        self.thread.join()
        print("Stopped reading data")


    def recieveData(self):
        self.recievingData = True
        while self.recievingData:
            # print("Waiting for data")
            part, addr = self.s.recvfrom(self.BUFF_SIZE)
            # print(part, addr)
            data = b''
            data += part
            while len(part) > self.BUFF_SIZE:
                # print("looping")
                part = self.s.recvfrom(self.BUFF_SIZE)
                # print(len(part))
                data += part
            self.lastData = data
            print(data)
            as_float = np.array([[float(x.strip()) for x in data.decode().split(',')]])
            self.recievedData = np.vstack((self.recievedData, as_float))

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...