def __init__(self, port, host, max_connection): self.logger = ClientLogger() threading.Thread.__init__(self) #threading.Thread.setDaemon(True) self.host = host self.semaphore = Semaphore(max_connection) # For Handling threads synchronization self.port = port # this port it will listen to self.sock = socket() #不能重复绑定,添加异常捕获, #重复绑定时,捕获异常,偏移端口 try: self.sock.bind((self.host, self.port)) # bind socket to address self.sock.listen(max_connection) except: ''' new_port = hash(str(self.port)) % 10000 self.sock.bind((self.host, new_port)) # bind socket to address self.sock.listen(max_connection) ''' #print("The port is already in use. we change your port to another one: ", new_port) print("This port is already listening.") self.logger.writingLog(logging.INFO, "This port is already listening.")
def __init__(self): print("WELCOME TO PEER TO PEER SHARING FILE SYSTEM\n") print("-" * 15, "Only after registration can you join the network", "-" * 15) self.logger = ClientLogger() #print("*" * 10, "This is Peer" + PEER_ID[-1:] + " ", "*" * 10) self.logger.writingLog(logging.INFO, ("*" * 10) + "This is Peer" + str(PEER_ID[-1:]) + " " + str("*" * 10)) self.portMutex = 0 self.flag = True #服务器健全标志 while True: try: # Getting Choice From Peer Choice = input( "TYPE :(1)REGISTER (2) SEARCH (3) DOWNLOAD (4) LIST_ALL (5)LIST_LOCAL_FILES (6)Reconnect the server (7)EXIT\n" ) if Choice == REGISTER: #Peer_id = input("Enter PEER ID 4 digit: ") # Getting PEER_ID Peer_id = PEER_ID self.file_name = input( "Enter File name: " ) # Getting file_name will be shared content = self.getContent(self.file_name) if content == "File does not exist.": print("Stop this registration.") self.logger(logging.ERROR, "Stop this registration.") else: md5 = self.getMd5(self.file_name, content) self.Peer_port = int( Peer_id ) # Convert Peer_port to int and store as attribute self.registerInServer( md5, self.flag ) # connect with server and send command to register the file if self.portMutex == 0: Start_PeerListener( self.Peer_port, HOST ) # After Register The File Listen to PEER_ID Port for sharing files self.portMutex += 1 else: print("This peer is listening...") self.logger.writingLog( logging.INFO, "This peer is listening...") elif Choice == SEARCH: self.SearchInServer( self.flag ) # Connect with server and send command to search for file name elif Choice == DOWNLOAD: Peer_id = input( "Enter PEER ID 4 digit: " ) # Taking PEER_ID and file_name i want to Download file from while Peer_id == PEER_ID: Peer_id = input( "You cannot download the local file, please enter another node ID: " ) file_name = input("Enter File name: ") self.Download(int(Peer_id), file_name) elif Choice == LIST_ALL: # SHOW ALL Sharing files that registered in Server self.List_all(self.flag) elif Choice == EXIT: self.logger.writingLog(logging.INFO, "client closed.") input("enter once to quit.") break elif Choice == LIST_LOCAL_FILES: self.getLocalFiles() elif Choice == RECONNECT: so = self.detectServer(HOST, PORT) if not so: print("Unable to connect to server.") self.logger.writingLog(logging.ERROR, "Unable to connect to server.") else: so.close() self.flag = True print( "Successfully connect to server, switch to centralized mode." ) self.logger.writingLog( logging.INFO, "Successfully connect to server, switch to centralized mode." ) else: print("Wrong choice. please enter another rigth choice.") self.logger.writingLog( logging.WARNING, "Wrong choice. please enter another rigth choice.") continue except: print("Unknown error. Please try again.") self.logger.writingLog(logging.ERROR, "Unknown error. Please try again.") return
class Peer_Server: # Connect Peer with Centeral-Server def __init__(self): print("WELCOME TO PEER TO PEER SHARING FILE SYSTEM\n") print("-" * 15, "Only after registration can you join the network", "-" * 15) self.logger = ClientLogger() #print("*" * 10, "This is Peer" + PEER_ID[-1:] + " ", "*" * 10) self.logger.writingLog(logging.INFO, ("*" * 10) + "This is Peer" + str(PEER_ID[-1:]) + " " + str("*" * 10)) self.portMutex = 0 self.flag = True #服务器健全标志 while True: try: # Getting Choice From Peer Choice = input( "TYPE :(1)REGISTER (2) SEARCH (3) DOWNLOAD (4) LIST_ALL (5)LIST_LOCAL_FILES (6)Reconnect the server (7)EXIT\n" ) if Choice == REGISTER: #Peer_id = input("Enter PEER ID 4 digit: ") # Getting PEER_ID Peer_id = PEER_ID self.file_name = input( "Enter File name: " ) # Getting file_name will be shared content = self.getContent(self.file_name) if content == "File does not exist.": print("Stop this registration.") self.logger(logging.ERROR, "Stop this registration.") else: md5 = self.getMd5(self.file_name, content) self.Peer_port = int( Peer_id ) # Convert Peer_port to int and store as attribute self.registerInServer( md5, self.flag ) # connect with server and send command to register the file if self.portMutex == 0: Start_PeerListener( self.Peer_port, HOST ) # After Register The File Listen to PEER_ID Port for sharing files self.portMutex += 1 else: print("This peer is listening...") self.logger.writingLog( logging.INFO, "This peer is listening...") elif Choice == SEARCH: self.SearchInServer( self.flag ) # Connect with server and send command to search for file name elif Choice == DOWNLOAD: Peer_id = input( "Enter PEER ID 4 digit: " ) # Taking PEER_ID and file_name i want to Download file from while Peer_id == PEER_ID: Peer_id = input( "You cannot download the local file, please enter another node ID: " ) file_name = input("Enter File name: ") self.Download(int(Peer_id), file_name) elif Choice == LIST_ALL: # SHOW ALL Sharing files that registered in Server self.List_all(self.flag) elif Choice == EXIT: self.logger.writingLog(logging.INFO, "client closed.") input("enter once to quit.") break elif Choice == LIST_LOCAL_FILES: self.getLocalFiles() elif Choice == RECONNECT: so = self.detectServer(HOST, PORT) if not so: print("Unable to connect to server.") self.logger.writingLog(logging.ERROR, "Unable to connect to server.") else: so.close() self.flag = True print( "Successfully connect to server, switch to centralized mode." ) self.logger.writingLog( logging.INFO, "Successfully connect to server, switch to centralized mode." ) else: print("Wrong choice. please enter another rigth choice.") self.logger.writingLog( logging.WARNING, "Wrong choice. please enter another rigth choice.") continue except: print("Unknown error. Please try again.") self.logger.writingLog(logging.ERROR, "Unknown error. Please try again.") return #overrided by xiaofeng def registerInServer(self, _md5, _flag): # Connect and Send command to Register ''' s = socket() s.connect((HOST, PORT)) ''' if not _flag: #print("System has switched to distributed mode.") self.logger.writingLog(logging.INFO, "System has switched to distributed mode.") self.registerInDistributed(_md5) return s = self.detectServer(HOST, PORT) if s == None: self.flag = False print("System has switched to distributed mode.") self.registerInDistributed(_md5) return data = pickle.dumps( self.Regiserdata(self.Peer_port, self.file_name, _md5)) s.send(data) state = s.recv(1024) print(state.decode('utf-8')) # Receive Confirmation of Registration self.logger.writingLog(logging.INFO, state.decode('utf-8')) s.close() def registerInDistributed(self, _md5): #读取本地目录文件 dir = self.getDirectory() #向目录中除了本节点外的其他客户端节点发送消息 self.registerToOtherNodes(dir, self.Peer_port, self.file_name, _md5) def registerToOtherNodes(self, _dir, _port, _filename, _md5): index = 0 #print(str(_infor[0])) port_set = set() #集合用于避免重复发送 for i in _dir: #print(i) if i["peer_id"] == str(_port) or i["peer_id"] in port_set: #跳过本节点和已经发送过的节点 continue else: #组装数据,发送信息 msgHead = REGISTER_CLIENT data = [msgHead, _port, _filename, _md5] data = pickle.dumps(data) s = socket() s.connect((HOST, int(i["peer_id"]))) s.send(data) s.close() index += 1 #print("Register speed: ", index) self.logger.writingLog(logging.INFO, "Register speed: " + str(index)) port_set.add(i["peer_id"]) def SearchInServer( self, _flag ): # Connect and Send command to Server for Specific File_name ''' s = socket() s.connect((HOST, PORT)) ''' if not _flag: #print("System has switched to distributed mode.") self.logger.writingLog(logging.INFO, "System has switched to distributed mode.") self.searchInDistributed() return s = self.detectServer(HOST, PORT) if s == None: self.flag = False print("System has switched to distributed mode.") self.searchInDistributed() return file_name = input("Enter File Name : ") data = pickle.dumps(self.SearchData(file_name)) s.send(data) ret_data = pickle.loads(s.recv(1024)) self.print_list(ret_data[0], ret_data[1]) # Return List of Files contain that name s.close() def searchInDistributed(self): file_name = input("Enter File Name : ") #print("Reading local data...") self.logger.writingLog(logging.INFO, "Reading local data...") od = OpeDir() od.searchRecord(file_name) def List_all( self, _flag ): # Connect and Send command to Server to Show all Exiting Files ''' s = socket() s.connect((HOST, PORT)) ''' if not _flag: #print("System has switched to distributed mode.") self.logger.writingLog(logging.INFO, "System has switched to distributed mode.") self.List_all_distrubuted() return s = self.detectServer(HOST, PORT) if s == None: print("System has switched to distributed mode.") self.List_all_distrubuted() self.flag = False return data = pickle.dumps(str(LIST_ALL)) s.send(data) ret_data = pickle.loads(s.recv(1024)) self.print_list(ret_data[0], ret_data[1]) # Return all exiting files s.close() def List_all_distrubuted(self): od = OpeDir() od.listAll() #overrided by xiaofeng. #该函数为了打包数据 def Regiserdata(self, Peer_port, file_name, _md5): # for formatting the return to pickle return [REGISTER, Peer_port, file_name, _md5] def print_list(self, Files, keys): # print all List if len(Files) > 0: print("Peer_Id | File_name | Checksum | Date_added :\n") for item in Files: print(" ", item[keys[0]], " ", item[keys[1]], " ", item[keys[2]], " ", item[keys[3]]) else: print( "There is no file has this name or there is no file in server at all\n" ) self.logger.writingLog( logging.INFO, "There is no file has this name or there is no file in server at all\n" ) def SearchData( self, file_name ): # Command for Search contains file_name, SEARCH indicator command return [SEARCH, file_name] def Download( self, Peer_id, file_name ): # Connect and Send request for downloading from specific PEER_PORT s = socket() #print("0") s.connect((HOST, Peer_id)) #print("1") data = pickle.dumps([DOWNLOAD, str(file_name)]) s.send(data) #print("2") #file_path = os.path.join(os.getcwd(), '..') # Organizing the path of file that will be Download ''' file_path = "../" file_path = os.path.join(file_path, "Peer" + PEER_ID[-1:] + 'Files') file_path = os.path.join(file_path, "downloads") print(file_path) ''' if "windows" in platform.system() or "Windows" in platform.system(): file_path = "..\\Peer" + PEER_ID[ -1:] + "Files\\downloads\\" + file_name # Organizing the path of file that will be Download elif "Linux" in platform.system(): file_path = "../Peer" + PEER_ID[ -1:] + "Files/downloads/" + file_name #print(file_path) with open(file_path, 'wb') as myfile: while True: data = s.recv(1024) if not data: myfile.close() break myfile.write(data) s.close() print('File Downloaded Successfully') self.logger.writingLog(logging.INFO, 'File Downloaded Successfully') print(file_name, "is in /Peer", PEER_ID[-1:] + "Files/downloads") self.logger.writingLog( logging.INFO, str(file_name) + "is in /Peer" + str(PEER_ID[-1:]) + "Files/downloads") #xf added #get md5 num of file def getMd5(self, _filename, _content): try: m = hashlib.md5() icontent = str(_filename + _content) ucontent = icontent.encode(encoding="utf8") m.update(ucontent) str_md5 = m.hexdigest() return str_md5 except: #print(_filename, " md5 failed.") self.logger.writingLog(logging.ERROR, str(_filename) + " md5 failed.") return "md5 failed" #xf added #get file's content def getContent(self, _filename): #make absolute path #judge win or linux #now, we couldn't support mac os if "windows" in platform.system() or "Windows" in platform.system(): file_path = "..\\Peer" + PEER_ID[ -1:] + "Files\\Uploads\\" # Organizing the path of file that will be Download elif "Linux" in platform.system(): file_path = "../Peer" + PEER_ID[-1:] + "Files/Uploads/" file_path = file_path + str(_filename) try: f = open(file_path, "r", encoding="utf-8") content = f.read() f.close() except: content = None print(file_path, " doesn't exist.") self.logger.writingLog(logging.INFO, str(file_path) + " doesn't exist.") if content: return content else: return "File does not exist." def getLocalFiles(self): if "windows" in platform.system() or "Windows" in platform.system(): file_path = "..\\Peer" + PEER_ID[ -1:] + "Files\\Uploads\\" # Organizing the path of file that will be Download elif "Linux" in platform.system(): file_path = "../Peer" + PEER_ID[-1:] + "Files/Uploads/" localFiles = os.listdir(file_path) print("file name:") for i in localFiles: print(i) print("-" * 15) print( "It's over. You can't share files that don't already exist on your computer. If you want to share new files, just copy them to uploads folder." ) def detectServer(self, _host, _port): s = socket() time = 1 flag = False #连接成功标志 while flag == False and time <= DETECT_TIME: s = socket() try: print("Connecting to server...") self.logger.writingLog(logging.WARNING, "Connecting to server...") s.connect((_host, _port)) flag = True time += 1 print("Successfully connect to server") self.logger.writingLog(logging.INFO, "Successfully connect to server") except: print( "Connection to server failed. Reconnect after 5 seconds..." ) self.logger.writingLog( logging.WARNING, "Connection to server failed. Reconnect after 5 seconds..." ) TIME.sleep(5) #等待5秒 time += 1 if flag: return s else: print( "The maximum number of retries is reached and the connection to the server fails.Switch to distributed mode...." ) self.logger.writingLog( logging.ERROR, "The maximum number of retries is reached and the connection to the server fails.Switch to distributed mode..." ) return None def getDirectory(self): #print("Read local directory...") self.logger.writingLog(logging.INFO, "Read local directory...") with open("dir.data", "rb") as file: dir = pickle.load(file) #print(type(dir[0])) return dir
class PeerListener(threading.Thread): def __init__(self, port, host, max_connection): self.logger = ClientLogger() threading.Thread.__init__(self) #threading.Thread.setDaemon(True) self.host = host self.semaphore = Semaphore(max_connection) # For Handling threads synchronization self.port = port # this port it will listen to self.sock = socket() #不能重复绑定,添加异常捕获, #重复绑定时,捕获异常,偏移端口 try: self.sock.bind((self.host, self.port)) # bind socket to address self.sock.listen(max_connection) except: ''' new_port = hash(str(self.port)) % 10000 self.sock.bind((self.host, new_port)) # bind socket to address self.sock.listen(max_connection) ''' #print("The port is already in use. we change your port to another one: ", new_port) print("This port is already listening.") self.logger.writingLog(logging.INFO, "This port is already listening.") def run(self): print("And This Peer is Ready For Sharing his File\n") self.logger.writingLog(logging.INFO, "And This Peer is Ready For Sharing his File\n") while True: conn, addr = self.sock.accept() #print("Got Connection From ", addr[0], " : ", addr[1]) self.logger.writingLog(logging.INFO, "Got Connection From " + str(addr[0]) + " : " + str(addr[1])) request = pickle.loads(conn.recv(1024)) if request[0] == DOWNLOAD: # Organizing the path of file that will be shared ''' file_path = os.path.join(os.getcwd(), '..') file_path = os.path.join(file_path, "Peer" + PEER_ID[-1:] + 'Files') file_path = os.path.join(file_path, "Uploads") ''' file_name = request[1] if "windows" in platform.system() or "Windows" in platform.system(): file_path = "..\\Peer" + PEER_ID[-1:] +"Files\\Uploads\\" + file_name # Organizing the path of file that will be Download elif "Linux" in platform.system(): file_path = "../Peer" + PEER_ID[-1:] + "Files/Uploads/" +file_name Full_path = file_path self.semaphore.acquire() with open(Full_path, "rb") as myfile: # Start Transfer File to Other Peer while True: l = myfile.read(2014) while (l): conn.send(l) l = myfile.read(1024) if not l: myfile.close() conn.close() break self.semaphore.release() #print('File Sent') self.logger.writingLog(logging.INFO, "File sent.") print("TYPE :(1)REGISTER (2) SEARCH (3) DOWNLOAD (4) LIST_ALL (5)LIST_LOCAL_FILES (6)Reconnect the server (7)EXIT\n") elif request[0] == REGISTER_CLIENT: #print("client register") self.logger.writingLog(logging.INFO, "client register") od = OpeDir() od.insertRecord(request) #print(request) else: #print("I got the directory.") self.logger.writingLog(logging.INFO, "Got the directory") #持久保存在本地 with open("dir.data", "wb") as file: pickle.dump(request, file) #print("Local directory caching is complete. ", len(request)) self.logger.writingLog(logging.INFO, "Local directory caching is complete. " + str(len(request)))