我尝试构建一个使用Python的套接字,线程和tkinter模块的应用程序。该应用程序是关于服务器和客户端之间的消息传递。如果只有一个客户端连接到服务器,则程序运行正常。但是,当第二个客户端连接服务器时,客户端名称会相互混合。我想设计一个服务器可以知道任何消息的发送者的应用程序。当两个客户端连接到服务器然后,其中一个客户端向服务器发送消息时,消息的发送者在服务器屏幕上只能看到两次,然后消息的发送者将是最后一个连接器的客户端。
以下是代码:
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
#!/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()
提前致谢...
答案 0 :(得分:0)
问题解决了,以下是代码:
<强> 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 强>
#!/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()