'''SocketTransport implements TCP socket interface for Transport.''' import socket from select import select from .transport import Transport class SocketTransportClient(Transport): def __init__(self, device, *args, **kwargs): device = device.split(':') if len(device) < 2: device = ('0.0.0.0', int(device[0])) else: device = (device[0], int(device[1])) self.socket = None super(SocketTransportClient, self).__init__(device, *args, **kwargs) def _open(self): self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.socket.connect(self.device) self.filelike = self.socket.makefile() def _close(self): self.socket.close() self.socket = None self.filelike = None def ready_to_read(self): rlist, _, _ = select([self.socket], [], [], 0) return len(rlist) > 0 def _write(self, msg, protobuf_msg): self.socket.sendall(msg) def _read(self): try: (msg_type, datalen) = self._read_headers(self.filelike) return (msg_type, self.filelike.read(datalen)) except socket.error: print("Failed to read from device") return None class SocketTransport(Transport): def __init__(self, device, *args, **kwargs): device = device.split(':') if len(device) < 2: device = ('0.0.0.0', int(device[0])) else: device = (device[0], int(device[1])) self.socket = None self.client = None self.filelike = None super(SocketTransport, self).__init__(device, *args, **kwargs) def _open(self): self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) #self.socket.setblocking(0) self.socket.bind(self.device) self.socket.listen(5) def _disconnect_client(self): print("Disconnecting client") if self.client != None: self.client.close() self.client = None self.filelike = None def _close(self): self._disconnect_client() self.socket.close() self.socket = None def ready_to_read(self): if self.filelike: # Connected rlist, _, _ = select([self.client], [], [], 0) return len(rlist) > 0 else: # Waiting for connection rlist, _, _ = select([self.socket], [], [], 0) if len(rlist) > 0: (self.client, ipaddr) = self.socket.accept() print("Connected", ipaddr[0]) self.filelike = self.client.makefile() return self.ready_to_read() return False def _write(self, msg, protobuf_msg): if self.filelike: # None on disconnected client try: self.filelike.write(msg) self.filelike.flush() except socket.error: print("Socket error") self._disconnect_client() def _read(self): try: (msg_type, datalen) = self._read_headers(self.filelike) return (msg_type, self.filelike.read(datalen)) except Exception: print("Failed to read from device") self._disconnect_client() return None