""" @author Georg Hopp """ import errno import socket import Transport from Socket import Socket, CONTINUE ACC_CONTINUE = CONTINUE + ( errno.ENETDOWN, errno.EPROTO, errno.ENOPROTOOPT, errno.EHOSTDOWN, errno.ENONET, errno.EHOSTUNREACH, errno.EOPNOTSUPP ) class TcpSocket(Socket): def __init__(self, host, port, con_ttl=30): super(TcpSocket, self).__init__(host, port, socket.SOCK_STREAM, con_ttl) self.remote = None def bind(self): super(TcpSocket, self).bind() self.socket.listen(128) self._listen = True def connect(self): with self._addrinfo(): self.socket.settimeout(self._con_ttl) self.socket.connect(self._sa) self.socket.settimeout(None) self.socket.setblocking(0) def accept(self): try: con, remote = self.socket.accept() except socket.error as error: if error.errno not in ACC_CONTINUE: raise Transport.Error(Transport.Error.ERR_FAILED) return None try: host, port = con.getpeername() except Exception as error: # Here we should destinguish the addr_family... # Port is only available for INET and INET6 but not for UNIX. # Currently I don't support UNIX so i don't change it now. host = addr[0] port = addr[1] con.setblocking(0) newsock = type(self)(host, port, self._con_ttl) newsock.socket = con newsock.remote = remote return newsock def recv(self, size): data = '' try: data = self.socket.recv(size) except socket.error as error: if error.errno not in CONTINUE: raise Transport.Error(Transport.Error.ERR_FAILED) return None if not data: raise Transport.Error(Transport.Error.ERR_REMOTE_CLOSE) return (data, self.remote) def send(self, data, remote=None): send = 0 try: if self.socket: send = self.socket.send(data) except socket.error as error: if error.errno not in CONTINUE: if error.errno == errno.ECONNRESET: raise Transport.Error(Transport.Error.ERR_REMOTE_CLOSE) else: raise Transport.Error(Transport.Error.ERR_FAILED) return send # vim: set ft=python et ts=4 sw=4 sts=4: