【发布时间】:2021-10-21 22:44:28
【问题描述】:
我在一个 tcp 聊天室工作,当我运行它时,它显示昵称和谁加入,但消息没有通过,并且在第四次尝试发送消息后显示错误
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\f\AppData\Local\Programs\Python\Python38-32\lib\tkinter\__init__.py", line 1883, in __call__
return self.func(*args)
File "besthost.py", line 59, in write
self.sock.send(message.encode('utf-8'))
ConnectionAbortedError: [WinError 10053] An established connection was aborted by the software in your host machine
主机文件是
import socket
import threading
import tkinter
import tkinter.scrolledtext
from tkinter import simpledialog
HOST = '127.0.0.1'
PORT = 9091
class Client:
def __init__(self, host, port):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.connect((host, port))
msg = tkinter.Tk()
msg.withdraw()
self.nickname = simpledialog.askstring("nickname", "please choose a nickname", parent=msg)
self.gui_done = False
self.running = True
gui_thread = threading.Thread(target=self.gui_loop)
receive_thread = threading.Thread(target=self.receive)
gui_thread.start()
receive_thread.start()
def gui_loop(self):
self.win = tkinter.Tk()
self.win.configure(bg="darkolivegreen")
self.chat_label = tkinter.Label(self.win, text="chat", bg="lightgray")
self.chat_label.config(font=("arial", 12))
self.chat_label.pack(padx=20, pady=5)
self.text_area = tkinter.scrolledtext.ScrolledText(self.win)
self.text_area.pack(padx=20, pady=5)
self.text_area.config(state='disabled')
self.msg_label = tkinter.Label(self.win, text="message", bg="lightgray")
self.msg_label.config(font=("arial", 12))
self.msg_label.pack(padx=20, pady=5)
self.input_area = tkinter.Text(self.win, height =3)
self.input_area.pack(padx=20,pady=5)
self.send_button = tkinter.Button(self.win, text="send", command=self.write)
self.send_button.config(font=("arial", 12))
self.send_button.pack(padx=20, pady=5)
self.gui_done = True
self.win.protocol("WM_DELETE_WINDOW", self.stop)
self.win.mainloop()
def write(self):
message = f"{self.nickname}:{self.input_area.get('1.0', 'end')}"
self.sock.send(message.encode('utf-8'))
self.input_area.delete('1.0', 'end')
def stop(self):
self.running = False
self.win.destroy()
self.sock.close()
exit(0)
def receive(self):
while self.running:
try:
message = self.sock.recv(1024).decode('utf-8')
if message=='NICK':
self.sock.send(self.nickname.encode('utf-8'))
else:
if self.gui_done:
self.text_area.config(state='normal')
self.text_area.insert('end', message)
self.text_area.yview('end')
self.text_area.config(state='disabled')
except ConnectionAbortedError:
break
except:
print("error")
self.sock.close()
break
client = Client(HOST, PORT)
服务器文件是
import socket
import threading
HOST = '127.0.0.1'
PORT = 9091
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((HOST, PORT))
server.listen()
clients = []
nicknames = []
def broadcast(message):
for client in clients:
client.send(message)
def handle(client):
while True:
try:
message = client.recv(1024).decode('utf-8')
print(f"{nicknames[client.index(client)]})")
broadcast(message)
except:
index = clients.index(client)
clients.remove(client)
client.close()
nickname = nicknames[index]
nicknames.remove(nickname)
break
def receive():
while True:
client, address = server.accept()
print(f"connected with {str(address)}!")
client.send("NICK".encode('utf-8'))
nickname = client.recv(1024)
nicknames.append(nickname)
clients.append(client)
print(f"nicknames of client is {nickname}")
broadcast(f"{nickname} connected successfully!\n".encode('utf-8'))
client.send("connected to the server".encode('utf-8'))
thread = threading.Thread(target=handle, args=(client,))
thread.start()
print("server running")
receive()
我尝试搜索,但我没有看到有人遇到这个问题,我认为没有任何编程错误
如果有人知道出了什么问题,请告诉我。 谢谢
【问题讨论】:
-
首先,在您的客户端中,您永远不会破坏
msg窗口。其次,您不应该从创建tk.Tk()窗口的线程以外的线程访问tkinter小部件/函数。第三,这个问题看起来像一个socket的错误问题。如果我是正确的,请从问题中删除tkinter标签。 -
我在 init 中的 tkinter 中也出现错误,如错误框中所示
-
您使用了
command=self.write,因此在来自tkinter/__init__.py的回溯中将显示为return self.func(*args)。实际错误来自socket.write(...)。 -
也许首先使用
print()来查看执行了哪一行代码以及变量中有什么。它被称为"print debuging"。也许代码看起来是正确的,但你可能会以错误的顺序运行函数,双方可能同时等待消息,然后它就会出现问题。 -
你不必在
f-string中使用str()
标签: python python-3.x sockets tkinter