class Client_wzk(object): def __init__(self, mytop): self.top = mytop self.ip_entry = tk.Entry(self.top, width=80) self.port_entry = tk.Entry(self.top, width=80) self.passwd_entry = tk.Entry(self.top, width=80) self.send_entry = tk.Entry(self.top, width=80) self.recv_entry = tk.Text(self.top, width=80) self.hostIP = '127.0.0.1' self.hostPort = 9999 self.s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.pc = PrpCrypt("keyskeyskeyskeys") def startClient(self, ip, portNum): # ip = self.ip_entry.get() # portNum = int(self.port_entry.get()) # passwd = self.passwd_entry.get() print("start client", ip, portNum) # self.s.bind((ip, portNum)) # print(self.s) print('\033[0;32m Client \'{}, {}\' on\nYou can now start chatting...\033[0m\n'.format(ip, portNum)) send_t = threading.Thread(target=self.send_thread, args=(self.s,)) # send thread send_t.setDaemon(True) send_t.start() recv_t = threading.Thread(target=self.recv_thread, args=(self.s,)) # recv thread recv_t.setDaemon(True) recv_t.start() def login(self): ip = self.ip_entry.get() portNum = self.port_entry.get() self.s.bind((ip, int(portNum))) # for i in range(5): # 5 times to input correct passwd # portNum = int(self.port_entry.get()) passwd = self.passwd_entry.get() loginInfo = '$login' + ip + "," + portNum + ":" + passwd encrypt_data = self.pc.encrypt(loginInfo.encode('utf-8')) self.s.sendto(encrypt_data, (self.hostIP, self.hostPort)) print(loginInfo) resp, addr = self.s.recvfrom(1024) # response from server if self.pc.decrypt(resp) == b"pass": # account and passwd ok, then start client self.recv_entry.insert(0.0, "Login\n") print("params", ip, portNum) self.startClient(ip, int(portNum)) elif self.pc.decrypt(resp) == b"failed": # varifi failed, can try again, but not more than 5 times # self.ip_entry.delete(0,20) # self.port_entry.delete(0,20) self.passwd_entry.delete(0, 20) self.s.close() # need to improve self.recv_entry.insert(0.0, "Wrong passwd for this account") print("try again") else: # unexpected resp self.passwd_entry.delete(0, 20) self.s.close() self.recv_entry.insert(0.0, "Wrong passwd for this account") print("error") # break def send_thread(self, socket): print("send thread") inputData = self.send_entry.get().encode('utf-8') self.send_entry.delete(0, 100) if inputData == b"exit": # exit client # break return encrypt_data = self.pc.encrypt(inputData) socket.sendto(encrypt_data, (self.hostIP, self.hostPort)) def recv_thread(self, socket): while True: recvData, recvAddr = socket.recvfrom(1024) print("***recvdata", recvData) decrypted_data = self.pc.decrypt(recvData) print("***decdata", decrypted_data) if recvAddr != (self.hostIP, self.hostPort): # discard data not from host continue self.recv_entry.insert(100.100, decrypted_data.decode('utf-8')) # blocked def window(self): self.top.title('Chatting Room by Echo Wang') tk.Label(self.top, text='Chatting Room by Echo Wang') tk.Label(self.top, text='IP').grid(row=1) tk.Label(self.top, text='Port').grid(row=3) tk.Label(self.top, text='Passwd').grid(row=5) tk.Label(self.top, text='Send').grid(row=7) tk.Label(self.top, text='Recv').grid(row=9) self.ip_entry.grid(row=1, column=1) self.port_entry.grid(row=3, column=1) self.passwd_entry.grid(row=5, column=1) self.send_entry.grid(row=7, column=1) self.recv_entry.grid(row=9, column=1) login = tk.Button(self.top, text='Login', bg='green', command=self.login) print("login btn") sendData = tk.Button(self.top, text='Send', bg='green', command=lambda: self.send_thread(self.s)) login.grid(row=5, column=2) sendData.grid(row=7, column=2) return 0
class Server(object): def __init__(self): self.hostIP = '127.0.0.1' self.hostPort = 9999 self.pc = PrpCrypt("keyskeyskeyskeys") # 'ip,port':passwd self.passwds = { '127.0.0.1,9998': '9998', '127.0.0.1,9997': '9997', '127.0.0.1,9996': '9996' } def startServer(self): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # create socket object s.bind((self.hostIP, self.hostPort)) chattingHistory = {} # key for clientAddr, value for chatting data print("\033[0;32m Server on\033[0m\n") clients = [] # records for all clients while True: recvData, clientAddr = s.recvfrom(1024) # recieve data decrypted_data = self.pc.decrypt(recvData) print("recv data", decrypted_data) if decrypted_data[0:6] == b"$login": # login request info = decrypted_data[6:].split(b":") # passwd ok if self.passwds[info[0].decode('utf-8')] == info[1].decode( 'utf-8'): # s.sendto(b"pass", clientAddr) s.sendto(self.pc.encrypt(b"pass"), clientAddr) else: # s.sendto(b"failed", clientAddr) s.sendto(self.pc.encrypt(b"failed"), clientAddr) print("continue") continue chattingRcd = time.ctime() + '\n' + decrypted_data.decode( 'utf-8') + '\n' if clients.count( clientAddr ) == 0: # if this client is not recorded, then add it to list clients.append(clientAddr) chattingHistory[ clientAddr] = chattingRcd # add data to history else: chattingHistory[clientAddr] += chattingRcd showName = "Message From Client \'{0[0]}, {0[1]}\': \n".format( clientAddr) print(' ' + showName + decrypted_data.decode('utf-8')) # server is listening if decrypted_data == b'cmd -h': # search chatting history(what this client said) print("Client {} request to search chatting history\n".format( clientAddr)) tips = "Chatting history of client {}\n".format( clientAddr).encode('utf-8') encrypted_his = self.pc.encrypt( tips + chattingHistory[clientAddr].encode('utf-8')) s.sendto(encrypted_his, clientAddr) # private chatting elif decrypted_data.split( b',', 3 )[0] == b'cmd -prvt': # msg format:[cmd],[dip],[dport],[msg],split by ',' dip = decrypted_data.split(b',', 3)[1].decode('utf-8') dport = int(decrypted_data.split(b',', 3)[2].decode('utf-8')) msgBody = decrypted_data.split( b',', 3)[3] # cut cmd info and leave msg body to send encrypted_send = self.pc.encrypt( showName.encode('utf-8') + msgBody + b'\n') # encrypt s.sendto(encrypted_send, (dip, dport)) # public chatting else: for addr in clients: # forward data to all other clients if addr != clientAddr: # don't send to scr client encrypted_send = self.pc.encrypt( showName.encode('utf-8') + decrypted_data + b'\n') s.sendto(encrypted_send, addr) s.close() # close socket