简体   繁体   English

Python / socket / threading / tkinter:如何知道消息发件人?

[英]Python/socket/threading/tkinter: How to know the message sender?

I try to build an application that uses socket, threading and tkinter modules of Python. 我尝试构建一个使用Python的套接字,线程和tkinter模块的应用程序。 The application is about messaging of between a server and clients. 该应用程序是关于服务器和客户端之间的消息传递。 If only one client is connecting to the server, the program runs well as i wish. 如果只有一个客户端正在连接到服务器,则该程序将按我希望的那样运行良好。 However when the second client is connecting the server, the client names are mixed to each other. 但是,当第二个客户端连接服务器时,客户端名称会相互混合。 I wanted to design an application that the server could know the sender of any messages. 我想设计一个服务器可以知道任何消息发件人的应用程序。 When two clients connect to the server and then, one of them sends messages to the server, the sender of the messages can be seen only two times on the server screen then the sender of the messages will be the client that is the last connector. 当两个客户端连接到服务器,然后其中一个向服务器发送消息时,消息的发件人只能在服务器屏幕上看到两次,然后消息的发件人将是最后一个连接器。

Here are the codes: 以下是代码:

server.py server.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from datetime import datetime
import socket
import threading
try:
    import Tkinter as tk
except ImportError:
    import tkinter as tk


root = tk.Tk()
root.title("Server")

text = tk.Text(master=root)
text.pack(expand=True, fill="both")

entry = tk.Entry(master=root)
entry.pack(expand=True, fill="x")

frame = tk.Frame(master=root)
frame.pack()


def buttons():
    for i in "Connect", "Send", "Clear", "Exit":
        b = tk.Button(master=frame, text=i)
        b.pack(side="left")
        yield b


b1, b2, b3, b4, = buttons()


class Server:
    clients = []

    def __init__(self):
        self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    def connect(self):
        self.s.bind(("", 12345))
        self.s.listen(10)
        now = str(datetime.now())[:-7]
        text.insert("insert", "Date: {}\nConnected.\n".format(now))
        self.condition()

    def accept(self):
        c, addr = self.s.accept()
        self.clients.append((c, addr))
        text.insert("insert", "Date: {}\n{} connected.\n".format(str(datetime.now())[:-7], addr))

    def receive(self):
        for i in self.clients:

            def f():
                data = str(i[0].recv(1024))[1:]
                now = str(datetime.now())[:-7]
                if len(data) == 2:
                    pass
                else:
                    text.insert("insert", "\nDate: {}\n{}: {}\n".format(now, i[1], data))

            t1_2_1 = threading.Thread(target=f)
            t1_2_1.start()

    def condition(self):
        while True:
            t1_1 = threading.Thread(target=self.accept)
            t1_1.daemon = True
            t1_1.start()
            t1_1.join(1)
            t1_2 = threading.Thread(target=self.receive)
            t1_2.daemon = True
            t1_2.start()
            t1_2.join(1)

    def send(self):
        respond = str(entry.get())
        now = str(datetime.now())[:-7]
        entry.delete("0", "end")
        try:
            for i in self.clients:
                i.sendall(bytes(respond.encode("utf-8")))
            text.insert("insert", "\nDate: {}\nServer: {}\n".format(now, respond))
        except BrokenPipeError:
            text.insert("insert", "\nDate: {}\nClient has been disconnected.\n".format(now))


s1 = Server()


def connect():
    t1 = threading.Thread(target=s1.connect)
    t1.start()


def send():
    t2 = threading.Thread(target=s1.send)
    t2.start()


def clear():
    text.delete("1.0", "end")


def destroy():
    root.destroy()


if __name__ == "__main__":
    b1.configure(command=connect)
    b2.configure(command=send)
    b3.configure(command=clear)
    b4.configure(command=destroy)
    t0 = threading.Thread(target=root.mainloop)
    t0.run()

client.py client.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from datetime import datetime
import socket
import threading
try:
    import Tkinter as tk
except ImportError:
    import tkinter as tk


root = tk.Tk()
root.title("Client")

text = tk.Text(master=root)
text.pack(expand=True, fill="both")

entry = tk.Entry(master=root)
entry.pack(expand=True, fill="x")

frame = tk.Frame(master=root)
frame.pack()


def buttons():
    for i in "Connect", "Send", "Clear", "Exit":
        b = tk.Button(master=frame, text=i)
        b.pack(side="left")
        yield b


b1, b2, b3, b4 = buttons()


class Client:
    def __init__(self):
        self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    def connect(self):
        self.s.connect(("", 12345))
        now = str(datetime.now())[:-7]
        text.insert("insert", "Date: {}\nConnected.\n".format(now))
        self.receive()

    def receive(self):
        while True:
            data = str(self.s.recv(1024))[1:]
            now = str(datetime.now())[:-7]
            if len(data) == 2:
                pass
            else:
                text.insert("insert", "\nDate: {}\nServer: {}\n".format(now, data))

    def send(self):
        respond = str(entry.get())
        now = str(datetime.now())[:-7]
        entry.delete("0", "end")
        try:
            self.s.sendall(bytes(respond.encode("utf-8")))
            text.insert("insert", "\nDate: {}\nClient: {}\n".format(now, respond))
        except BrokenPipeError:
            text.insert("insert", "\nDate: {}\Server has been disconnected. koptu.\n".format(now))
            self.s.close()


c1 = Client()


def connect():
    t1 = threading.Thread(target=c1.connect)
    t1.start()


def send():
    t2 = threading.Thread(target=c1.send)
    t2.start()


def clear():
    text.delete("1.0", "end")


def destroy():
    root.destroy()


if __name__ == "__main__":
    b1.configure(command=connect)
    b2.configure(command=send)
    b3.configure(command=clear)
    b4.configure(command=destroy)
    t0 = threading.Thread(target=root.mainloop)
    t0.run()

Thanks in advance... 提前致谢...

Screenshot 屏幕截图

The problem is solved, here are the codes: 问题已解决,代码如下:

server.py server.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from datetime import datetime
import socket
import threading
try:
    import Tkinter as tk
except ImportError:
    import tkinter as tk


root = tk.Tk()
root.title("Server")

text = tk.Text(master=root)
text.pack(expand=True, fill="both")

entry = tk.Entry(master=root)
entry.pack(expand=True, fill="x")

frame = tk.Frame(master=root)
frame.pack()


def buttons():
    for i in "Connect", "Send", "Clear", "Exit":
        b = tk.Button(master=frame, text=i)
        b.pack(side="left")
        yield b


b1, b2, b3, b4, = buttons()


class Server:
    clients = []

    def __init__(self):
        self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    def connect(self):
        self.s.bind(("", 12346))
        self.s.listen(10)
        now = str(datetime.now())[:-7]
        text.insert("insert", "({}) : Connected.\n".format(now))
        self.condition()

    def accept(self):
        c, addr = self.s.accept()
        self.clients.append(c)
        data = c.recv(1024)
        text.insert("insert", "({}) : {} connected.\n".format(str(datetime.now())[:-7], str(data)[1:]))

    def receive(self):
        for i in self.clients:

            def f():
                data = str(i.recv(1024))[2:-1]
                now = str(datetime.now())[:-7]
                if len(data) == 0:
                    pass
                else:
                    text.insert("insert", "({}) : {}\n".format(now, data))

            t1_2_1 = threading.Thread(target=f)
            t1_2_1.start()

    def condition(self):
        while True:
            t1_1 = threading.Thread(target=self.accept)
            t1_1.daemon = True
            t1_1.start()
            t1_1.join(1)
            t1_2 = threading.Thread(target=self.receive)
            t1_2.daemon = True
            t1_2.start()
            t1_2.join(1)

    def send(self):
        respond = "Server: {}".format(str(entry.get()))
        now = str(datetime.now())[:-7]
        entry.delete("0", "end")
        try:
            for i in self.clients:
                i.sendall(bytes(respond.encode("utf-8")))
            text.insert("insert", "({}) : {}\n".format(now, respond))
        except BrokenPipeError:
            text.insert("insert", "({}) : Client has been disconnected.\n".format(now))


s1 = Server()


def connect():
    t1 = threading.Thread(target=s1.connect)
    t1.start()


def send():
    t2 = threading.Thread(target=s1.send)
    t2.start()


def clear():
    text.delete("1.0", "end")


def destroy():
    root.destroy()
    exit()


if __name__ == "__main__":
    b1.configure(command=connect)
    b2.configure(command=send)
    b3.configure(command=clear)
    b4.configure(command=destroy)
    t0 = threading.Thread(target=root.mainloop)
    t0.run()

client.py client.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from datetime import datetime
import socket
import threading
try:
    import Tkinter as tk
except ImportError:
    import tkinter as tk


root = tk.Tk()
root.title("Client")

text = tk.Text(master=root)
text.pack(expand=True, fill="both")

entry = tk.Entry(master=root)
entry.pack(expand=True, fill="x")

frame = tk.Frame(master=root)
frame.pack()


def buttons():
    for i in "Connect", "Create A Nickname", "Send", "Clear", "Exit":
        b = tk.Button(master=frame, text=i)
        b.pack(side="left")
        yield b


b1, b2, b3, b4, b5 = buttons()


class Client:
    def __init__(self):
        self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.nickname = None

    def connect(self):
        now = str(datetime.now())[:-7]
        if self.nickname is not None:
            try:
                self.s.connect(("", 12346))
                text.insert("insert", "({}) : Connected.\n".format(now))
                self.s.sendall(bytes("{}".format(self.nickname).encode("utf-8")))
                self.receive()
            except ConnectionRefusedError:
                text.insert("insert", "({}) : The server is not online.\n".format(now))
        else:
            text.insert("insert", "({}) : You must create a nickname.\n".format(now))

    def receive(self):
        while True:
            data = str(self.s.recv(1024))[2:-1]
            now = str(datetime.now())[:-7]
            if len(data) == 0:
                pass
            else:
                text.insert("insert", "({}) : {}\n".format(now, data))

    def do_nothing(self):
        pass

    def create_nickname(self):
        b2.configure(command=self.do_nothing)
        _frame = tk.Frame(master=root)
        _frame.pack()
        new_entry = tk.Entry(master=_frame)
        new_entry.grid(row=0, column=0)
        new_button = tk.Button(master=_frame, text="Accept Your Nickname")
        new_button.grid(row=1, column=0)

        def nickname_command():
            now = str(datetime.now())[:-7]
            if new_entry.get() == "":
                text.insert("insert", "({}) : You must write a nickname.\n".format(now))
            else:
                self.nickname = new_entry.get()
                _frame.destroy()
                text.insert("insert", "({}) : Nickname has changed to: '{}'\n".format(now, self.nickname))
                b2.configure(command=c1.create_nickname)

        new_button.configure(command=nickname_command)

    def send(self):
        respond = "{}: {}".format(self.nickname, str(entry.get()))
        now = str(datetime.now())[:-7]
        entry.delete("0", "end")
        try:
            self.s.sendall(bytes(respond.encode("utf-8")))
            text.insert("insert", "({}) : {}\n".format(now, respond))
        except BrokenPipeError:
            text.insert("insert", "({}) : Server has been disconnected.\n".format(now))
            self.s.close()


c1 = Client()


def connect():
    t1 = threading.Thread(target=c1.connect)
    t1.start()


def send():
    t2 = threading.Thread(target=c1.send)
    t2.start()


def clear():
    text.delete("1.0", "end")


def destroy():
    root.destroy()


if __name__ == "__main__":
    b1.configure(command=connect)
    b2.configure(command=c1.create_nickname)
    b3.configure(command=send)
    b4.configure(command=clear)
    b5.configure(command=destroy)
    t0 = threading.Thread(target=root.mainloop)
    t0.run()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM