from sets import Set
import socket
from twisted.internet import interfaces, address
from twisted.persisted import styles
from twisted.python import log, reflect
from ops import AcceptExOp
from abstract import ConnectedSocket
from util import StateEventMachineType
import error
class ServerSocket(ConnectedSocket):
def __init__(self, sock, protocol, sf, sessionno):
ConnectedSocket.__init__(self, sock, protocol, sf)
self.logstr = "%s,%s,%s" % (self.protocol.__class__.__name__, sessionno, self.getHost())
self.repstr = "<%s #%s on %s>" % (self.protocol.__class__.__name__, sessionno, self.getPort())
self.startReading()
class ListeningPort(log.Logger, styles.Ephemeral, object):
__metaclass__ = StateEventMachineType
__implements__ = interfaces.IListeningPort,
events = ["startListening", "stopListening", "loseConnection", "acceptDone", "acceptErr"]
sockinfo = None
transport = ServerSocket
sessionno = 0
def __init__(self, addr, factory, backlog):
self.state = "disconnected"
self.addr = addr
self.factory = factory
self.backlog = backlog
self.accept_op = AcceptExOp(self)
def __repr__(self):
return "<%s on %s>" % (self.factory.__class__, self.getPort())
def handle_disconnected_startListening(self):
log.msg("%s starting on %s" % (self.factory.__class__, self.getPort()))
try:
skt = socket.socket(*self.sockinfo)
skt.bind(self.addr)
except socket.error, le:
raise error.CannotListenError, (None, None, le)
self.factory.doStart()
skt.listen(self.backlog)
self.socket = skt
self.state = "listening"
self.startAccepting()
def startAccepting(self):
self.accept_op.initiateOp(self.socket.fileno())
def handle_listening_acceptDone(self, sock, addr):
protocol = self.factory.buildProtocol(self.buildAddress(addr))
if protocol is None:
sock.close()
else:
s = self.sessionno
self.sessionno = s+1
transport = self.transport(sock, protocol, self, s)
protocol.makeConnection(transport)
if self.state == "listening":
self.startAccepting()
def handle_disconnected_acceptDone(self, sock, addr):
sock.close()
def handle_listening_acceptErr(self, ret, bytes):
# print "ono acceptErr", ret, bytes
self.stopListening()
def handle_disconnected_acceptErr(self, ret, bytes):
# print "ono acceptErr", ret, bytes
pass
def handle_listening_stopListening(self):
self.state = "disconnected"
self.socket.close()
log.msg('(Port %s Closed)' % (self.getPort(),))
self.factory.doStop()
handle_listening_loseConnection = handle_listening_stopListening
def handle_disconnected_stopListening(self):
raise error.NotListeningError
def logPrefix(self):
"""Returns the name of my class, to prefix log entries with.
"""
return reflect.qual(self.factory.__class__)
def connectionLost(self, reason):
pass
# stupid workaround for test_tcp.LoopbackTestCase.testClosePortInProtocolFactory
disconnected = property(lambda self: self.state == "disconnected")
syntax highlighted by Code2HTML, v. 0.9.1