forked from lunixbochs/uberserver
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDispatcher.py
executable file
·94 lines (82 loc) · 3.61 KB
/
Dispatcher.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
import Multiplexer, Protocol, Client
import socket, thread, traceback
class Dispatcher:
def __init__(self, root, server):
self._root = root
self.server = server
self.poller = Multiplexer.BestMultiplexer()
self.socketmap = {}
self.workers = []
self.protocol = Protocol.Protocol(root, self)
# legacy vars
self.thread = thread.get_ident()
self.num = 0
def pump(self):
self.poller.register(self.server)
self.poller.pump(self.callback)
def callback(self, inputs, outputs, errors):
try:
for s in inputs:
if s == self.server:
try:
conn, addr = self.server.accept()
except socket.error, e:
if e[0] == 24: # ulimit maxfiles, need to raise ulimit
self._root.console_write('Maximum files reached, refused new connection.')
else:
raise socket.error, e
client = Client.Client(self._root, conn, addr, self._root.session_id)
self.addClient(client)
else:
try:
data = s.recv(1024)
if data:
if s in self.socketmap: # for threading, just need to pass this to a worker thread... remember to fix the problem for any calls to handler, and fix msg ids (handler.thread)
self.socketmap[s].Handle(data)
else:
print 'Problem, sockets are not being cleaned up properly.'
else:
raise socket.error, 'Connection closed.'
except socket.error:
self.removeSocket(s)
for s in outputs:
try:
self.socketmap[s].FlushBuffer()
except KeyError:
self.removeSocket(s)
except socket.error:
self.removeSocket(s)
except: self._root.error(traceback.format_exc())
def rebind(self):
self.protocol = Protocol.Protocol(self._root, self)
for client in self._root.clients.values():
client.Bind(protocol=self.protocol)
def addClient(self, client):
self._root.clients[self._root.session_id] = client
self._root.session_id += 1
client.Bind(self, self.protocol)
if not client.static:
self.socketmap[client.conn] = client
self.poller.register(client.conn)
def removeClient(self, client, reason='Quit'):
client.Remove()
def removeSocket(self, s):
if s in self.socketmap:
self.socketmap[s].Remove()
def finishRemove(self, client, reason='Quit'):
if client.static or not client._protocol: return # static clients don't disconnect
client._protocol._remove(client, reason)
s = client.conn
if s in self.socketmap: del self.socketmap[s]
self.poller.unregister(s)
try:
s.shutdown(socket.SHUT_RDWR)
s.close()
except socket.error: #socket shut down by itself ;) probably got a bad file descriptor
try:
s.close()
except socket.error:
pass # in case shutdown was called but not close.
except AttributeError:
pass
self._root.console_write('Client disconnected from %s, session ID was %s'%(client.ip_address, client.session_id))