summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcliechti <cliechti@f19166aa-fa4f-0410-85c2-fa1106f25c8a>2003-10-04 23:45:51 +0000
committercliechti <cliechti@f19166aa-fa4f-0410-85c2-fa1106f25c8a>2003-10-04 23:45:51 +0000
commitfb947cb47fa5d0c2e4f05e39bc7ef609059d9d72 (patch)
tree0206041312110e1cc2a11e8ac155dc45531f1161
parent1354878539d96310f25f4ae43ba99775f5de5d8a (diff)
downloadpyserial-git-fb947cb47fa5d0c2e4f05e39bc7ef609059d9d72.tar.gz
- bugfixes
- code cleanup
-rw-r--r--pyserial/examples/tcp_serial_redirect.py157
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 ---"