from BitTornado.bencode import bencode, bdecode, Bencached import SocketServer, time, sys # get socket server, handler objects import struct try: sum except: sum = lambda numberlist:reduce(lambda x,y:x+y,numberlist,0.0) def recv_size(the_socket): #data length is packed into 4 bytes total_len=0;total_data=[];size=sys.maxint size_data=sock_data='';recv_size=8192 count = 0 while total_len=5: print 'count:', count sock_data=the_socket.recv(recv_size) #if count < 2 : # print '////////:', sock_data if not total_data: if len(sock_data)>4: size_data+=sock_data size=struct.unpack('>i', size_data[:4])[0] recv_size=size if recv_size>524288:recv_size=524288 total_data.append(size_data[4:]) else: size_data+=sock_data else: total_data.append(sock_data) total_len=sum([len(i) for i in total_data ]) return ''.join(total_data) def now(): return time.ctime(time.time()) # server handle class receiver(SocketServer.BaseRequestHandler): nodeobj = None def handle(self): # on each client connect # print self.client_address, now() # show this client's address timeout = 1 total_data=[];data=''; begin=time.time() count = 0 alldata = recv_size(self.request) try: data = bdecode(alldata) except: print 'error when decoding' return cmd = data['CMD'] if cmd == 'BC': #get my own caches [randCacheList, buddyCacheList]= self.__class__.nodeobj.getCaches() #remote peer info plus its caches remotepeer = data['DAT'] remotepeer['ip'] = self.client_address[0] remotepeer['time']= int(time.time()) #get remote peer info only peerRecord = {} peerRecord['ip']= remotepeer['ip'] peerRecord['time'] = remotepeer['time'] peerRecord['peer_id'] = remotepeer['peer_id'] peerRecord['port'] = remotepeer['port'] # remote peer's user_pref if remotepeer.has_key('user_pref'): self.__class__.nodeobj.mergeUserPrefCache(remotepeer) peerRecord['has_pref'] = True else : peerRecord['has_pref'] = False # remote peer ip add to its randcache remotepeer['rand'].append(peerRecord) hostpeerid = self.__class__.nodeobj.info['peer_id'] port = self.__class__.nodeobj.info['ownport'] peerid = [] for apeer in remotepeer['rand']: try: peerid.append(apeer['peer_id']) except: print 'wrong with remote random cache \ in server:', remotepeer['rand'] sys.exit() break #debug information print '[peer:', hostpeerid,']', 'get from ', \ '[ peer:',remotepeer['peer_id'],', port', remotepeer['port'], ']', \ 'peer id in remote randcache:', peerid if remotepeer.has_key('buddy') : self.__class__.nodeobj.mergeCaches(remotepeer['rand'],\ remotepeer['buddy']) else: self.__class__.nodeobj.mergeCaches(remotepeer['rand'],'null') Cur_time = int(time.time()) peerMSG = {'rand':randCacheList, \ 'peer_id': hostpeerid, 'port':port,'time':Cur_time} if remotepeer['request_pref'] == True: peerMSG['user_pref'] = self.__class__.nodeobj.info['user_pref'] sendoff = {'CMD':'ACK','DAT':peerMSG} data = bencode(sendoff) else: data = bencode({'CMD':'UNK','DAT':''}) self.request.sendall(struct.pack('>i', len(data))+data) self.request.close() # print 'closed this connection!' # server handle class monitor_receiver(SocketServer.BaseRequestHandler): nodeobj = None # in this case the supernode obj def handle(self): # on each client connect #print self.client_address, now() # show this client's address timeout = 1 total_data=[];data='';begin=time.time() count = 0 alldata = recv_size(self.request) try: data = bdecode(alldata) except: print 'error when decoding' return cmd = data['CMD'] if cmd == 'REG': #print 'what we have now:', data peer = data['DAT'] print 'peer:', peer['peer_id'], 'registered' peer['ip'] = self.client_address[0] peer['time']= int(time.time()) self.__class__.nodeobj.randCache.add(peer) # {'ip','port','peer_id','time'} self.__class__.nodeobj.status['numREG'] += 1 sendoff = {'CMD':'ACK','DAT':'REGED'} data = bencode(sendoff) #print peer,'ack:', sendoff elif cmd == 'INI': # get initial ipaddress self.__class__.nodeobj.status['numBS'] += 1 print 'what we have now:', data [numPeers,peerID] = data['DAT'] size = self.__class__.nodeobj.randCache.getLength() if size == 0: data = bencode({'CMD':'ACK','DAT':'null'}) else: peers = self.__class__.nodeobj.randCache.getRandomPeers(numPeers) data = bencode({'CMD':'ACK','DAT':peers}) elif cmd == 'OPL': self.__class__.nodeobj.status['numOPL'] += 1 print 'what we have now:', data peerid = int(data['DAT']) userprofile = self.__class__.nodeobj.userprofiles[peerid] data = bencode({'CMD':'ACK','DAT':userprofile}) else: data = bencode({'CMD':'UNK','DAT':''}) self.request.sendall(struct.pack('>i', len(data))+data) #self.request.sendall(data) self.request.close() #print 'closed this connection!'