Python-TCP客户机/服务器到Seri

2024-10-04 11:27:17 发布

您现在位置:Python中文网/ 问答频道 /正文

这是我第一次尝试使用Python语言。我试图创建一个到服务器的TCP客户机连接,但是如果客户机连接在经过一定次数的尝试后失败,则将该连接恢复到服务器模式。在服务器模式下,如果收到命令或经过一定的时间段(某种类型的重新连接计时器),它将能够尝试返回到客户端模式。在客户端或服务器模式下,来自外部服务器的所有常规通信将通过串行接口/dev/ttyUSB0发出,反之亦然(仅限客户端模式)。通信必须在两个方向上进行检查,以便其他进程可以排队排除通过的特定命令,这可能包括从串行或TCP端口发送原始消息。也将有一个辅助串行接口发送命令到连接的蜂窝调制解调器。我假设这必须通过某种线程方法来实现,以便能够同时监视串行和网络连接,但是我对Python还不够熟悉,不知道它是如何工作的。在

以下是我目前所掌握的情况:

import sys
import socket
import thread
import time
import string
import serial
import serial.threaded

#######################################
#global variable
connected = 0 #holds the connection status, 0 : disconnected , 1 : connected
HBCounter = 0 #a counter that is related to heartbeat sent from server
HBSend = 0 #controls the flow of hearbeat sent by client
soc = socket.socket()#client socket
#######################################
class SerialPort(serial.threaded.Protocol):
    """serial->socket"""

    def __init__(self):
        self.socket = None

    def __call__(self):
        return self

    def data_received(self, data):
        if self.socket is not None:
            self.socket.sendall(data)
#######################################
#this function tries to connect to the server
def tcpConnect():
    global connected, soc
    connected = 0
    s = socket.socket()          #socket object
    host = x.x.x.x
    port = 51015  # The server port
    try:
        s.connect((host, port)) #connecting to server
    except:
        tcpConnect() #retry on failure
    connected = 1
    soc = s
    thread.start_new_thread(tcpReadLine,(s,parse)) #read thread
#######################################
#timer class, needs user defined callback function(cb)
class timer:
    def __init__(self,timeout,func):
        self.timeout = timeout
        self.func = func
    def start(self):
        go = 1
        curTime = time.time()
        while go:
            _time = time.time()
            if _time - curTime >= self.timeout:
                go = 0
        self.timerTimeout()
    def run(self):
        thread.start_new_thread(self.start,())
    def timerTimeout(self):
        self.func()
        self.run()
#######################################
#reads tcp socket, will call cb function when a whole line is detected
def tcpReadLine(tempSoc,func):
    lock = checkConnection()
    while lock == 0:
        lock = checkConnection()#checks if we are connected
    print ("connected")
    str = ""
    while lock:
        try:
            str += tempSoc.recv(1)
        except:
            lock = checkConnection()  
        if string.find(str,"\r\n") != -1 :
          func(str)
          str = ""
          lock = checkConnection()
#######################################
#parses the incoming data, for now we only print it, tcpRead line callback function
def parse(data):
    global HBCounter
    HBCounter = 0;  #we recently recieved data so connection is alive
    ser.write(data)
#######################################
#timer callback function
def CBTimeout():
    global HBSend, HBCounter, connected
    HBSend = HBSend + 1
    HBCounter = HBCounter + 1
    if  HBCounter >= 3 : # 3*timeout value inactivity from server, reset connection
        soc.close()
        thread.start_new_thread(tcpConnect,()) #starts a thread to manage connection
        HBCounter = 0
    if HBSend >= 2: # 2*timeout value inactivity from us, sending heartbeat
        tcpSend("HB\r\n")
#######################################
#sending routine
def tcpSend(data):
    global HBSend
    lock = checkConnection()
    while lock == 0:
        lock = checkConnection()#checks if we are connected
    try:
        soc.send(data)
        HBSend = 0 #recently sent data
    except:
        print "write failure"
#######################################
def checkConnection():
    return connected
#######################################
#######################################
#main program starts here
ser = serial.serial_for_url('/dev/ttyUSB0', do_not_open=True) #connect to serial port of Meshnet board
ser.baudrate = 19200
ser.parity = 'N'
ser.rtscts = False
ser.xonxoff = False

serModem = serial.Serial('/dev/ttyACM0',115200,timeout=1) #connect to USB Modem

try:
    ser.open()
    serModem.open()
except serial.SerialException as e:
    sys.stderr.write('Could not open serial port {}: {}\n'.format(ser.name, e))
    sys.exit(1)

dataSerial = SerialPort()
serial_worker = serial.threaded.ReaderThread(ser, dataSerial)
modemSerial = SerialPort()
modem_serial_worker = serial.threaded.ReaderThread(serModem, modemSerial)
serial_worker.start()
modem_serial_worker.start()
thread.start_new_thread(tcpConnect,()) #starts a thread to manage connection  
timer1 = timer(10,CBTimeout) #create a new timer with 10 sec timeout
timer1.run() #run timer

Tags: toimportselflockdatatimedeftimeout