8 from xml
.dom
.minidom
import parse
, parseString
9 from threading
import Lock
16 PASSWORD
= "changethis"
23 SERVERREQUEST
= "i_want_server"
24 SERVEROFFER
= "Want_server?"
25 SERVERKILL
= "DIE_server!!"
26 YOUTHERE
= "you_there?"
27 IMHERE
= "yeah,i'm_here"
32 LIST
= "peoples_on_server"
33 SOMEONEJOINED
= "dude,someone_joined"
34 SOMEONELEFT
= "someone_left"
35 YOUROUT
= "get_lost_punk"
36 LETTER
= "listen_to_me"
46 def __init__(self
, config
):
53 self
.outgoing_lock
= Lock()
54 self
.incoming_lock
= Lock()
56 self
.broadcast
= socket(AF_INET
, SOCK_DGRAM
)
57 self
.message
= socket(AF_INET
, SOCK_DGRAM
)
59 self
.message_lock
= Lock()
63 self
.configuration
= config
65 if (config
.has_key('broadcast')):
66 self
.broadcast
.bind(('', config
['broadcast']))
68 print "Server.__init__(): No broadcast socket number chosen, using", BROADCAST
69 self
.broadcast
.bind(('', BROADCAST
))
71 if (config
.has_key('message')):
72 self
.message
.bind(('', config
['message']))
74 print "Server.__init__(): No message socket number chosen, using", MESSAGE
75 self
.message
.bind(('', MESSAGE
))
79 print "Server.receive() beginning..."
81 self
.message
.settimeout(TIMEOUT
)
85 self
.message_lock
.acquire()
86 data_in
= self
.message
.recvfrom(BUFSIZE
)
87 self
.message_lock
.release()
92 self
.incoming_lock
.acquire()
93 self
.incoming
.append(data_in
)
94 print "Got data", data_in
95 self
.incoming_lock
.release()
101 print "Server.send() beginning..."
103 while (self
.running
):
105 if (len(self
.outgoing
)):
107 self
.outgoing_lock
.acquire()
108 print "Server.send(): Acquired outgoing_lock"
110 data_out
= self
.outgoing
.pop(0)
112 self
.outgoing_lock
.release()
113 print "Server.send(): Released outgoing_lock"
115 self
.message
.sendto(data_out
[0], data_out
[1])
116 print "Server.send(): Sent data", data_out
119 def process_in(self
):
121 print "Server.process_in() beginning..."
123 while (self
.running
):
125 if (len(self
.incoming
)):
128 self
.incoming_lock
.acquire()
129 print "Server.process_in(): Acquired incoming_lock"
131 data_in
= self
.incoming
.pop(0)
133 self
.incoming_lock
.release()
134 print "Server.process_in(): Released incoming_lock"
136 if (data_in
[0][:len(WANTIN
)] == WANTIN
):
137 print "Server.process_in(): Received WANTIN"
139 response
= [YOUREIN
, data_in
[1]]
141 self
.outgoing_lock
.acquire()
142 print "Server.process_in(): Acquired outgoing_lock"
144 self
.outgoing
.append(response
)
146 self
.outgoing_lock
.release()
147 print "Server.process_in(): Released outgoing_lock"
149 self
.members
[data_in
[0][len(WANTIN
) + 1:]] = data_in
[1]
151 if (data_in
[0][:len(YOUTHERE
)] == YOUTHERE
):
152 print "Server.process_in(): Received YOUTHERE, responding with IMHERE"
154 response
= [IMHERE
, data_in
[1]]
156 self
.outgoing_lock
.acquire()
157 print "Server.process_in(): Acquired outgoing_lock"
159 self
.outgoing
.append(response
)
161 self
.outgoing_lock
.release()
162 print "Server.process_in(): Released outgoing_lock"
164 if (data_in
[0][:len(IMOUT
)] == IMOUT
):
165 print "Server.process_in(): Received IMOUT, notifying clients"
170 for name
, address
in self
.members
.iteritems():
171 if (data_in
[1] == address
):
172 response
[0] = SOMEONELEFT
+ " " + name
173 name_to_delete
= name
175 if (name_to_delete
!= ''):
176 del self
.members
[name_to_delete
]
178 for name
, address
in self
.members
.iteritems():
179 response
[1] = address
181 self
.outgoing_lock
.acquire()
182 print "Server.process_in(): Acquired outgoing_lock"
184 self
.outgoing
.append(response
)
186 self
.outgoing_lock
.release()
187 print "Server.process_in(): Released outgoing_lock"
189 if (data_in
[0] == GETLIST
):
190 print "Server.process_in(): Received GETLIST, responding with member list"
192 for name
, address
in self
.members
.iteritems():
193 if (address
== data_in
[1]):
196 response
[0] = LIST
+ " "
197 response
[1] = address
199 for iname
, iaddress
in self
.members
.iteritems():
201 response
[0] = response
[0] + iname
+ " "
203 self
.outgoing_lock
.acquire()
205 print "Server.process_in(): Acquired outgoing_lock"
207 self
.outgoing
.append(response
)
209 self
.outgoing_lock
.release()
210 print "Server.process_in(): Released outgoing_lock"
212 if (data_in
[0][:len(SERVERKILL
)] == SERVERKILL
):
213 print "Server.process_in(): Received SERVERKILL"
215 if (data_in
[0][len(SERVERKILL
) + 1:] == self
.configuration
['password']):
218 if (data_in
[0][:len(LETTER
)] == LETTER
):
219 print "Server.process_in(): Received LETTER"
223 the_data
= data_in
[0]
228 for name
in self
.members
.keys():
229 if self
.members
[name
] == data_in
[1]:
234 response
= [LETTER
+ ":" + origin
+ ":", []]
236 if the_data
[len(LETTER
):len(LETTER
)+2] == '::':
238 it_is
= the_data
[the_data
.find("::") + 2:]
241 for name
in self
.members
.keys():
245 responses
.append(response
)
246 responses
[-1][1] = self
.members
[name
]
250 it_is
= the_data
[the_data
.find(":", the_data
.find(":") + 1) + 1:]
253 string_parts
= the_data
[the_data
.find(":") + 1:
254 the_data
.find(":", the_data
.find(":") + 1)].split()
256 for dest
in string_parts
:
258 if self
.members
.has_key(dest
):
260 responses
.append(response
)
261 responses
[-1][1] = self
.members
[dest
]
263 for response_i
in responses
:
265 self
.outgoing_lock
.acquire()
266 self
.outgoing
.append(response_i
)
267 self
.outgoing_lock
.release()
271 def process_out(self
):
273 print "Server.process_out(): Not implemented yet."
277 def broadcast_listen(self
):
279 print "Listening on broadcast port:", self
.configuration
['broadcast']
281 broadcast_message
= SERVEROFFER
+ " " + str(self
.configuration
['message'])
282 broadcast_message
= broadcast_message
+ " " + self
.configuration
['name']
284 while (self
.running
):
285 data_in
= self
.broadcast
.recvfrom(BUFSIZE
)
287 if (data_in
[0][0:len(SERVERREQUEST
)] == SERVERREQUEST
):
288 new_message
= [broadcast_message
]
289 new_message
.append((data_in
[1][0], int(data_in
[0][len(SERVERREQUEST
) + 1:])))
291 self
.outgoing_lock
.acquire()
292 print "Server.broadcast_listen(): Acquired outgoing_lock"
294 self
.outgoing
.append(new_message
)
296 self
.outgoing_lock
.release()
297 print "Server.broadcast_listen(): Released outgoing_lock"
305 def parse_config(filename
):
307 parsed
= {'error': 1}
309 if (exists(filename
)):
310 dom
= parse(filename
)
312 print "parse_config():", filename
, "doesn't exist"
315 if (dom
.childNodes
[0].nodeName
== 'server_config'):
316 for node
in dom
.childNodes
[0].childNodes
:
318 if (node
.nodeName
== 'name' and len(node
.childNodes
)):
319 parsed
['name'] = node
.childNodes
[0].nodeValue
321 if (node
.nodeName
== 'password' and len(node
.childNodes
)):
322 parsed
['password'] = node
.childNodes
[0].nodeValue
324 if (node
.nodeName
== 'broadcast' and len(node
.childNodes
)):
325 parsed
['broadcast'] = int(node
.childNodes
[0].nodeValue
)
327 if (node
.nodeName
== 'message' and len(node
.childNodes
)):
328 parsed
['message'] = int(node
.childNodes
[0].nodeValue
)
334 def run(configuration
):
336 my_server
= Server(configuration
)
338 receive_thread
= threading
.Thread(target
=my_server
.receive
)
339 send_thread
= threading
.Thread(target
=my_server
.send
)
340 process_in_thread
= threading
.Thread(target
=my_server
.process_in
)
341 process_out_thread
= threading
.Thread(target
=my_server
.process_out
)
342 broadcast_thread
= threading
.Thread(target
=my_server
.broadcast_listen
)
344 receive_thread
.start()
347 process_in_thread
.start()
348 process_out_thread
.start()
349 broadcast_thread
.start()
351 receive_thread
.join()
353 broadcast_thread
.join()
354 process_in_thread
.join()
355 process_out_thread
.join()
359 def handler(signal
, frame
):
360 if (signal
== SIGINT
):
362 print "It should have ended"
366 # parsing command line options
368 if (len(sys
.argv
) > 1):
369 config_file
= sys
.argv
[1]
371 print "main(): No config file specified, using", CONFIG
374 parsed_config
= parse_config(config_file
)
376 if (parsed_config
['error']):
377 print "main(): Error parsing config, ending"
380 signal(SIGINT
, handler
)
384 if __name__
== '__main__':