Пример #1
0
 def obtain(self, filename):
     # define message
     msg = (
         "mid:"
         + str(self.pid)
         + "|"
         + str(2222 + self.pid * 10)
         + "|"
         + str(self.msgid)
         + ",search:"
         + filename
         + ",TTL=10"
     )
     mid = msg.split(",")[0].split(":")[1]
     # read mid_list from file 'msg_list'
     mid_list = rw.readList("msg_list.txt")
     # update mid_list
     mid_list.append(mid)
     rw.write("msg_list.txt", mid_list)
     # read name_list from file 'req_list'
     name_list = rw.readList("req_list.txt")
     # update name_list
     name_list.append(filename)
     rw.write("req_list.txt", name_list)
     # broadcast message to its neighbor
     for n in self.neighbor:
         self.s = socket.socket()
         self.host = socket.gethostname()
         self.port = 2222 + 10 * n
         print "connect port: " + str(self.port)
         self.s.connect((self.host, self.port))
         self.s.send(msg)
         self.s.close()
     print "searching... ..."
Пример #2
0
	def push(self, name, version):
		#send update msg to all peers
		self.msgid += 1
		msg = 'mid:' + str(self.pid) + '|' + str(self.port) + '|update|' + str(self.msgid) + ',update:' + name + ',version:' + str(version)
		mid = msg.split(',')[0].split(':')[1]
		#read mid_list from file 'msg_list'
		mid_list = rw.readList('msg_list.txt')
		#update mid_list
		mid_list.append(mid)
		rw.write('msg_list.txt', mid_list)
		broadcast = autobroadcast.Auto(msg, self.neighbor)
		broadcast.start()
		broadcast.join()
Пример #3
0
	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
Пример #4
0
	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()