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):
self.stopListening()
def handle_disconnected_acceptErr(self, 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
disconnected = property(lambda self: self.state == "disconnected")