diff options
author | cliechti <cliechti@f19166aa-fa4f-0410-85c2-fa1106f25c8a> | 2003-10-04 23:45:51 +0000 |
---|---|---|
committer | cliechti <cliechti@f19166aa-fa4f-0410-85c2-fa1106f25c8a> | 2003-10-04 23:45:51 +0000 |
commit | fb947cb47fa5d0c2e4f05e39bc7ef609059d9d72 (patch) | |
tree | 0206041312110e1cc2a11e8ac155dc45531f1161 /pyserial/examples | |
parent | 1354878539d96310f25f4ae43ba99775f5de5d8a (diff) | |
download | pyserial-git-fb947cb47fa5d0c2e4f05e39bc7ef609059d9d72.tar.gz |
- bugfixes
- code cleanup
Diffstat (limited to 'pyserial/examples')
-rw-r--r-- | pyserial/examples/tcp_serial_redirect.py | 157 |
1 files changed, 94 insertions, 63 deletions
diff --git a/pyserial/examples/tcp_serial_redirect.py b/pyserial/examples/tcp_serial_redirect.py index 0816ad8..e55d53a 100644 --- a/pyserial/examples/tcp_serial_redirect.py +++ b/pyserial/examples/tcp_serial_redirect.py @@ -1,70 +1,103 @@ #!/usr/bin/env python -#(C)2002 Chris Liechti >cliecht@gmx.net> +#(C)2002-2003 Chris Liechti <cliechti@gmx.net> #redirect data from a TCP/IP connection to a serial port and vice versa -#requires python 2.2 'cause socket.sendall is used +#requires Python 2.2 'cause socket.sendall is used -#this program is a hack - do not use it as an example of clean -#threading programming! it's only an example for pyserial. +"""USAGE: tcp_serial_redirect.py [options] +Simple Serial to Network (TCP/IP) redirector. -import sys, os, serial, threading, getopt, socket, time +Options: + -p, --port=PORT serial port, a number, defualt = 0 or a device name + -b, --baud=BAUD baudrate, default 9600 + -r, --rtscts enable RTS/CTS flow control (default off) + -x, --xonxoff enable software flow control (default off) + -P, --localport TCP/IP port on which to run the server (default 7777) -def reader(): - """loop forever and copy serial->console""" - global connection - while 1: - try: - if connection: - connection.sendall(s.read(s.inWaiting())) - else: - time.sleep(0.2) #lower CPU usage... - except socket.error, msg: - print msg - if connection: connection.close() - connection = None - except: - pass +Note: no security measures are implemeted. Anyone can remotely connect +to this service over the network. +Only one connection at once is supported. If the connection is terminaed +it waits for the next connect. +""" -def writer(): - """loop forever and copy console->serial""" - global connection - try: - while 1: - s.write(connection.recv(1024)) - except socket.error, msg: - print msg +import sys, os, serial, threading, getopt, socket +try: + True +except NameError: + True = 1 + False = 0 -#print a short help message -def usage(): - print >>sys.stderr, """USAGE: %s [options] - Simple Terminal Programm for the serial port. +class Redirector: + def __init__(self, serial, socket): + self.serial = serial + self.socket = socket - options: - -p, --port=PORT: serial port, a number, defualt = 0 or a device name - -b, --baud=BAUD: baudrate, default 9600 - -r, --rtscts: enable RTS/CTS flow control (default off) - -x, --xonxoff: enable software flow control (default off) - -P, --localport: TCP/IP port on which to run the server (default 7777) - """ % sys.argv[0] + def shortcut(self): + """connect the serial port to the tcp port by copying everything + from one side to the other""" + self.alive = True + self.thread_read = threading.Thread(target=self.reader) + self.thread_read.setDaemon(1) + self.thread_read.start() + self.writer() + + def reader(self): + """loop forever and copy serial->socket""" + while self.alive: + try: + data = self.serial.read(1) #read one, blocking + n = self.serial.inWaiting() #look if there is more + if n: + data = data + self.serial.read(n) #and get as much as possible + if data: + self.socket.sendall(data) #send it over TCP + except socket.error, msg: + print msg + #probably got disconnected + break + self.alive = False + + def writer(self): + """loop forever and copy socket->serial""" + while self.alive: + try: + data = self.socket.recv(1024) + if not data: + break + self.serial.write(data) #get a bunch of bytes and send them + except socket.error, msg: + print msg + #probably got disconnected + break + self.alive = False + self.thread_read.join() + + def stop(self): + """Stop copying""" + if self.alive: + self.alive = False + self.thread_read.join() if __name__ == '__main__': - connection = None + ser = serial.Serial() #parse command line options try: opts, args = getopt.getopt(sys.argv[1:], - "hp:b:rxec", - ["help", "port=", "baud=", "rtscts", "xonxoff", "echo", "cr"]) + "hp:b:rxP", + ["help", "port=", "baud=", "rtscts", "xonxoff", "localport"]) except getopt.GetoptError: # print help information and exit: - usage() + print >>sys.stderr, __doc__ sys.exit(2) - port = 0 - baudrate = 9600 - rtscts = 0 - xonxoff = 0 + ser.port = 0 + ser.baudrate = 9600 + ser.rtscts = False + ser.xonxoff = False + ser.timeout = 1 #required so that the reader thread can exit + localport = 7777 for o, a in opts: if o in ("-h", "--help"): #help text @@ -72,34 +105,30 @@ if __name__ == '__main__': sys.exit() elif o in ("-p", "--port"): #specified port try: - port = int(a) + ser.port = int(a) except ValueError: - port = a + ser.port = a elif o in ("-b", "--baud"): #specified baudrate try: - baudrate = int(a) + ser.baudrate = int(a) except ValueError: raise ValueError, "Baudrate must be a integer number" elif o in ("-r", "--rtscts"): - rtscts = 1 + ser.rtscts = True elif o in ("-x", "--xonxoff"): - xonxoff = 1 + ser.xonxoff = True elif o in ("-P", "--localport"): try: localport = int(a) except ValueError: - raise ValueError, "local port must be an integer number" + raise ValueError, "Local port must be an integer number" print "--- TCP/IP to Serial redirector --- type Ctrl-C / BREAK to quit" - #start serial->tcp/ip thread - r = threading.Thread(target=reader) - r.setDaemon(1) - r.start() try: - s = serial.Serial(port, baudrate, rtscts=rtscts, xonxoff=xonxoff) - except: - print "could not open port" + ser.open() + except serial.SerialException, e: + print "Could not open serial port %s: %s" % (ser.portstr, e) sys.exit(1) srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM) @@ -107,13 +136,15 @@ if __name__ == '__main__': srv.listen(1) while 1: try: + print "Waiting for connection..." connection, addr = srv.accept() print 'Connected by', addr #enter console->serial loop - writer() + r = Redirector(ser, connection) + r.shortcut() + print 'Disconnected' + connection.close() except socket.error, msg: print msg - if connection: connection.close() - connection = None print "\n--- exit ---" |