def monitor(self): nfileinfo = self.scan() nindex = nfileinfo[0] nct = nfileinfo[1] nlmt = nfileinfo[2] #check if the file has been delete or replaced or added if nct != self.ct or nindex != self.index: print 'files have been replaced!' else: if nlmt != self.lmt: for i in range(0, len(nlmt)): if nlmt[i] != self.lmt[i]: filename = nindex[i] print '%s has been modified!' % filename #update version number & last modified time in metadata file. self.meta_dict[filename]['version'] += 1 self.meta_dict[filename]['LMT'] = nlmt[i] meta_dict = rw.readDict('metadata.txt') meta_dict['original'] = self.meta_dict rw.write('metadata.txt', meta_dict) self.push(filename, self.meta_dict[filename]['version']) i += 1 #update the variable last modified time after each push. self.lmt = nlmt else: print 'everything is unchanged!' print nfileinfo
def __init__(self, pid, neighbor): #inital pushupdate thread parameter threading.Thread.__init__(self) #scan all the original file self.fileinfo = self.scan() self.index = self.fileinfo[0] self.ct = self.fileinfo[1] self.lmt = self.fileinfo[2] #read file metadata from metadata.txt self.meta_dict = rw.readDict('metadata.txt')['original'] self.pid = pid self.port = 2222 + self.pid * 10 self.neighbor = neighbor self.msgid = 0
def monitor(self): #check all download files, see if it's TTR Expired or not Dict = rw.readDict('metadata.txt') if 'download' in Dict.keys(): meta_dict = Dict['download'] count = [y for x,y in meta_dict.items()] for i in range(0, len(count)): if count[i]['state'] == 'valid': if time.time() >= count[i]['TTR'] + count[i]['LMT']: #alarm user file is TTR Expired count[i]['state'] = 'TTR Expired' filename = meta_dict.keys()[i] print '%s is expired, need to refresh' % filename #let user choose to update ot not cmd = raw_input('update or not ? (yes/no) : ') if cmd == 'yes': self.pull(filename, meta_dict[filename]) else: pass i += 1 else: pass
def reconn(self): #reconnect to response peer self.s = socket.socket() self.host = socket.gethostname() self.port = int(self.mid.split('|')[1]) self.s.connect((self.host, self.port)) print 'reconnect to ' + self.mid self.s.send(self.msg) #download metadata & file from response peer metadata = json.loads(self.s.recv(1024)) #download file by chunks i = 0 content = '' while i != 1: chunk = self.s.recv(1024) if len(chunk) == 0: i = 1 else: content += chunk self.s.close() path = os.path.join(os.getcwd(), 'files', 'download', self.name) rw.writeFile(path, content) #read name_list from file 'req_list' name_list = rw.readList('req_list.txt') #update name_list name_list.remove(self.name) rw.write('req_list.txt', name_list) #update metadata meta_dict = rw.readDict('metadata.txt') if 'download' in meta_dict.keys(): meta_dict['download'][self.name] = metadata else: file_dict = {} file_dict[self.name] = metadata meta_dict['download'] = file_dict rw.write('metadata.txt', meta_dict) print 'receive file: ' + self.name
def renew(iterm, name, data): meta_dict = rw.readDict('metadata.txt') meta_dict['download'][name][iterm] = data rw.write('metadata.txt', meta_dict) print 'renew ' + iterm + ': ' + data
def run(self): #define the server thread self.s = socket.socket() self.host = socket.gethostname() self.port = 2222 + self.pid * 10 self.s.bind((self.host, self.port)) self.s.listen(5) while True: #listen for connection c, addr = self.s.accept() print '\nGot connection from ', addr #initialize file index original_index = self.fileindex('original') download_index = self.fileindex('download') index = original_index + download_index #receive message msg = c.recv(1024) #parse & analyze message mid = msg.split(',')[0].split(':')[1] action = msg.split(',')[1].split(':')[0] name = msg.split(',')[1].split(':')[1] if action == 'search': print 'search ' + name ttl = msg.split(',')[2].split('=')[1] #read mid_list from file 'msg_list' mid_list = rw.readList('msg_list.txt') #decide broadcast or not if int(ttl) == 1 or mid in mid_list: print 'file dont need to pass' else: #update mid_list in file 'msg_list' mid_list.append(mid) rw.write('msg_list.txt', mid_list) #decrease the ttl value by 1 after broadcast for once rmsg = msg.rsplit(ttl, 1) msg = str(int(ttl)-1).join(rmsg) #start autobroadcast thread (details in autobroadcast.py module) broadcast = autobroadcast.Auto(msg, self.neighbor) broadcast.start() broadcast.join() if name in index: #check file's state meta_dict = rw.readDict('metadata.txt') if (name in original_index and (meta_dict['original'][name]['state'] == 'valid' or meta_dict['download'][name]['state'] == 'valid')): #start hitresponse thread (details in hitresponse.py module) msg = 'mid:' + str(self.pid) + '|' + str(self.port) + ',response:' + name hit = hitresponse.Hit(msg, mid) hit.start() hit.join() else: 'file state is not qualified' else: print 'no file match, pass to neighbors' elif action == 'update': print 'update ' + name #read mid_list from file 'msg_list' mid_list = rw.readList('msg_list.txt') #decide broadcast or not if mid in mid_list: print 'update dont need to pass' else: #update mid_list in file 'msg_list' mid_list.append(mid) rw.write('msg_list.txt', mid_list) #start autobroadcast thread (details in autobroadcast.py module) broadcast = autobroadcast.Auto(msg, self.neighbor) broadcast.start() broadcast.join() if name in download_index: #set file state to invalid meta_dict = rw.readDict('metadata.txt') meta_dict['download'][name]['state'] = 'invalid' rw.write('metadata.txt', meta_dict) else: print 'no file need to update, pass to neighbors' elif action == 'check': print 'check ' + name #check the original file's version version = int(msg.split(',')[2].split(':')[1]) TTR = int(msg.split(',')[3].split(':')[1]) meta_dict = rw.readDict('metadata.txt') if meta_dict['original'][name]['version'] == version: #if same version, send a new TTR. newTTR = 2 * TTR msg = 'mid:' + str(self.pid) + '|' + str(self.port) + ',checkresponse:' + name + ',state:valid,TTR:' + str(newTTR) else: #send Invalid & new version exist. msg = 'mid:' + str(self.pid) + '|' + str(self.port) + ',checkresponse:' + name + ',state:invalid' hit = hitresponse.Hit(msg, mid) hit.start() hit.join() elif action == 'checkresponse': print 'checkresponse ' + name #update the metadata state = str(msg.split(',')[2].split(':')[1]) if state == 'valid': TTR = int(msg.split(',')[3].split(':')[1]) #change TTR to 2TTR. (details in pullrenew.py module) pullrenew.renew('TTR', name, TTR) #change state from 'TTR Expired' back to 'valid' (details in pullrenew.py module) pullrenew.renew('state', name, state) elif state == 'invalid': #change state from 'TTR Expired' back to 'invalid' (details in pullrenew.py module) pullrenew.renew('state', name, state) elif action == 'response': #start reconnect thread (details in reconnect.py module) print 'response ' + name + ' from ' + mid #read name_list from file 'req_list' name_list = rw.readList('req_list.txt') #decide reconnect or not if name in name_list: msg = 'mid:' + str(self.pid) + '|' + str(self.port) + ',obtain:' + name connect = reconnect.Connect(msg, mid, name) connect.start() connect.join() else: print 'file has been obtained' elif action == 'obtain': print 'obtain ' + name #start transfer directly to original peer if name in original_index: path = os.path.join(os.getcwd(), 'files', 'original', name) metadata = rw.readDict('metadata.txt')['original'][name] elif name in download_index: path = os.path.join(os.getcwd(), 'files', 'download', name) metadata = rw.readDict('metadata.txt')['download'][name] #send metadata & file c.sendall(json.dumps(metadata)) #slice file into chunks by buffer content = rw.readFile(path) i = 0 while i <= len(content): chunk = buffer(content, i, 1024) c.sendall(chunk) i += 1024 print 'send file: ' + name c.close()