def remove_client(self, client, why='?'): try: name = client.getpeername() except: name = 'client %d' % client.fileno() logio('MUX > Closing %s: %s' % (name, why)) self.poller.unregister(client) self.clients.remove(client) client.close()
def close(self): logio('\nMUX > Closing...') for client in self.clients: client.close() if getattr(self, 'tty', None): self.tty.close() self.server.close() logio('MUX > Done! =)')
def run(self): try: self.tty = serial.Serial(self.device, self.baudrate, self.width, self.parity, self.stopbits, 1, self.xon, self.rtc) self.tty.setTimeout(0) # Non-blocking self.tty.flushInput() self.tty.flushOutput() self.poller.register(self.tty, _READ_ONLY) self.fd_to_socket[self.tty.fileno()] = self.tty logio('MUX > Serial port: %s @ %s' % (self.device, self.baudrate)) self.server.bind((self.host, self.port)) self.server.listen(5) self.poller.register(self.server, _READ_ONLY) self.fd_to_socket[self.server.fileno()] = self.server logio('MUX > Server: %s:%d' % self.server.getsockname()) logio('MUX > Use ctrl+c to stop...\n') while True: events = self.poller.poll(500) for fd, flag in events: # Get socket from fd s = self.fd_to_socket[fd] if flag & select.POLLHUP: self.remove_client(s, 'HUP') elif flag & select.POLLERR: self.remove_client(s, 'Received error') elif flag & (_READ_ONLY): # A readable server socket is ready to accept a connection if s is self.server: connection, client_address = s.accept() self.add_client(connection) # Data from serial port elif s is self.tty: data = s.read(80) for client in self.clients: client.send(data) # Data from client else: data = s.recv(80) # Client has data if data: self.tty.write(data) # Interpret empty result as closed connection else: self.remove_client(s, 'Got no data') except serial.SerialException as e: logio('\nMUX > Serial error: "%s". Closing...' % e) except socket.error as e: logio('\nMUX > Socket error: %s' % e.strerror) except (KeyboardInterrupt, SystemExit): pass finally: self.close()
def add_client(self, client): logio('MUX > New connection from', client.getpeername()) client.setblocking(0) self.fd_to_socket[client.fileno()] = client self.clients.append(client) self.poller.register(client, _READ_ONLY)
def _write_simple(x): sys.stdout.write(x) def _write_log(x): sys.stdout.write(x) log.write(x) # Setup log file writing if opts.file: logname = opts.file log = open(logname, 'w') logio('MUX > Logging output to', logname) write = _write_log else: write = _write_simple # Setup client server_address = ('localhost', opts.port) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(server_address) logio('MUX > Connected to %s:%d' % server_address) logio('MUX > format: [date time elapsed delta] line') logio('MUX > Use ctrl+c to stop...\n') # Init line catcher