Beispiel #1
0
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
Beispiel #2
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