Module Network
[hide private]
[frames] | no frames]

Source Code for Module Network

  1  ##################################################################### 
  2  # -*- coding: iso-8859-1 -*-                                        # 
  3  #                                                                   # 
  4  # Frets on Fire                                                     # 
  5  # Copyright (C) 2006 Sami Kyöstilä                                  # 
  6  #                                                                   # 
  7  # This program is free software; you can redistribute it and/or     # 
  8  # modify it under the terms of the GNU General Public License       # 
  9  # as published by the Free Software Foundation; either version 2    # 
 10  # of the License, or (at your option) any later version.            # 
 11  #                                                                   # 
 12  # This program is distributed in the hope that it will be useful,   # 
 13  # but WITHOUT ANY WARRANTY; without even the implied warranty of    # 
 14  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     # 
 15  # GNU General Public License for more details.                      # 
 16  #                                                                   # 
 17  # You should have received a copy of the GNU General Public License # 
 18  # along with this program; if not, write to the Free Software       # 
 19  # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,        # 
 20  # MA  02110-1301, USA.                                              # 
 21  ##################################################################### 
 22   
 23  import asyncore 
 24  import socket 
 25  import struct 
 26  import time 
 27  import StringIO 
 28   
 29  import Log 
 30   
 31  PORT = 12345 
 32   
33 -class ObjectCollection(dict):
34 - def __init__(self):
35 dict.__init__(self) 36 self.idCounter = -1 37 self.objMap = {}
38
39 - def add(self, object, id = None):
40 id = id or self.generateId() 41 self[id] = object 42 return id
43
44 - def id(self, object):
45 try: 46 return self.objMap[object] 47 except KeyError: 48 pass
49
50 - def __delitem__(self, id):
51 try: 52 del self.objMap[self[id]] 53 del self[id] 54 except KeyError: 55 pass
56
57 - def __setitem__(self, id, object):
58 self.objMap[object] = id 59 dict.__setitem__(self, id, object)
60
61 - def generateId(self):
62 self.idCounter += 1 63 return self.idCounter
64
65 -class Connection(asyncore.dispatcher):
66 - def __init__(self, sock = None):
67 asyncore.dispatcher.__init__(self, sock = sock) 68 self.id = None 69 self.server = None 70 self._buffer = [] 71 self._sentSizeField = False 72 self._receivedSizeField = 0 73 self._packet = StringIO.StringIO() 74 75 if not sock: 76 self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
77 78 #def __getattr__(self, name): 79 # print ">>>", name 80 # return asyncore.dispatcher.__getattr__(self, name) 81
82 - def connect(self, host, port = PORT):
83 assert self.id is None 84 85 asyncore.dispatcher.connect(self, (host, port)) 86 87 # do a blocking connect 88 n = 0 89 while not self.connected and n < 600: 90 communicate() 91 n += 1 92 if n > 100: 93 time.sleep(.1)
94
95 - def accept(self, id):
96 assert self.id is None 97 98 self.id = id 99 self._buffer.append(struct.pack("H", self.id)) 100 self.handleRegistration()
101
102 - def setServer(self, server):
103 self.server = server
104
105 - def handleConnect(self):
106 pass
107
108 - def handle_connect(self):
109 return self.handleConnect()
110
111 - def handle_read(self):
112 try: 113 if not self._receivedSizeField: 114 data = self.recv(2) 115 if data: 116 self._receivedSizeField = struct.unpack("H", data)[0] 117 return 118 data = self.recv(self._receivedSizeField) 119 if data: 120 self._receivedSizeField -= len(data) 121 self._packet.write(data) 122 if not self._receivedSizeField: 123 # The first packet contains the ID 124 if self.id is None: 125 self.id = struct.unpack("H", self._packet.getvalue())[0] 126 self.handleRegistration() 127 else: 128 self.handlePacket(self._packet.getvalue()) 129 self._packet.truncate() 130 self._packet.seek(0) 131 except socket.error, e: 132 Log.error("Socket error while receiving: %s" % str(e))
133
134 - def writable(self):
135 return len(self._buffer) > 0
136
137 - def sendPacket(self, packet):
138 self._buffer.append(packet)
139
140 - def handlePacket(self, packet):
141 pass
142
143 - def close(self):
144 asyncore.dispatcher.close(self) 145 self.handle_close()
146
147 - def handleClose(self):
148 if self.server: 149 self.server.handleConnectionClose(self) 150 self.id = None
151
152 - def handle_close(self):
153 return self.handleClose()
154
155 - def handleRegistration(self):
156 pass
157
158 - def handle_write(self):
159 try: 160 data = self._buffer[0] 161 if not self._sentSizeField: 162 self.send(struct.pack("H", len(data))) 163 self._sentSizeField = True 164 sent = self.send(data) 165 data = data[sent:] 166 if data: 167 self._buffer[0] = data 168 else: 169 self._buffer = self._buffer[1:] 170 self._sentSizeField = False 171 except socket.error, e: 172 Log.error("Socket error while sending: %s" % str(e))
173
174 -class Server(asyncore.dispatcher):
175 - def __init__(self, port = PORT, localOnly = True):
176 asyncore.dispatcher.__init__(self) 177 self.create_socket(socket.AF_INET, socket.SOCK_STREAM) 178 self.set_reuse_addr() 179 self.bind((localOnly and "localhost" or "", port)) 180 self.listen(5) 181 self.clients = {} 182 self.__idCounter = 0
183
184 - def handle_accept(self):
185 sock, addr = self.accept() 186 self.__idCounter += 1 187 conn = self.createConnection(sock = sock) 188 conn.setServer(self) 189 conn.accept(self.__idCounter) 190 self.clients[self.__idCounter] = conn 191 self.handleConnectionOpen(conn)
192
193 - def createConnection(self, sock):
194 return Connection(sock = sock)
195
196 - def handleConnectionOpen(self, connection):
197 pass
198
199 - def close(self):
200 asyncore.dispatcher.close(self) 201 self.handle_close()
202
203 - def handleClose(self):
204 for c in self.clients.values(): 205 c.close()
206
207 - def handle_close(self):
208 return self.handleClose()
209
210 - def handleConnectionClose(self, connection):
211 if connection.id in self.clients: 212 del self.clients[connection.id]
213
214 - def broadcastPacket(self, packet, ignore = [], meToo = True):
215 for c in self.clients.values(): 216 if not c.id in ignore: 217 c.sendPacket(packet) 218 if meToo: 219 self.clients.values()[0].handlePacket(packet)
220
221 - def sendPacket(self, receiverId, packet):
222 self.clients[receiverId].sendPacket(packet)
223
224 -def communicate(cycles = 1):
225 while cycles: 226 asyncore.poll(0, asyncore.socket_map) 227 cycles -= 1
228
229 -def shutdown():
230 asyncore.close_all()
231