You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
91 lines
2.4 KiB
91 lines
2.4 KiB
"""
|
|
@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:
|