В настоящее время я работаю над программой чата. Я следовал учебному пособию онлайн, и в результате получился работающий чат в реальном времени.
Он состоит из файла сервера и файла клиента.
Ошибка возникает, когда я закрываю файл клиента и присоединиться к тому же экземпляру сервера. Со стороны клиента я не могу отправить сообщение. В командной строке сервера выдает эту ошибку:
Waiting for connection...
192.168.0.81:61453 connected to server.
192.168.0.81:61456 connected to server.
Exception in thread Thread-3:
Traceback (most recent call last):
File "C:\Users\Rasmus\AppData\Local\Programs\Python\Python37\lib\threading.py", line 917, in _bootstrap_inner
self.run()
File "C:\Users\Rasmus\AppData\Local\Programs\Python\Python37\lib\threading.py", line 865, in run
self._target(*self._args, **self._kwargs)
File "C:\Users\Rasmus\Desktop\Programmering\troubleshoot\server.py", line 19, in handle_client
broadcast(bytes(msg, "utf8"))
File "C:\Users\Rasmus\Desktop\Programmering\troubleshoot\server.py", line 36, in broadcast
sock.send(bytes(prefix, "utf8")+msg)
ConnectionResetError: [WinError 10054] An existing connection was forcibly closed by the remote host
Насколько я могу прочитать по inte rnet, это потому, что существует активное соединение с того же адреса. Означает ли это, что программа не закрывает клиента должным образом?
Эта проблема также возникает, когда подключаются другие клиенты из других сетей.
Я не совсем новичок ie, но ни эксперт в Python, поэтому в глубоком объяснении очень ценится.
Server.py:
from socket import AF_INET, socket, SOCK_STREAM
from threading import Thread
def accept_incoming_connections():
while True:
client, client_address = SERVER.accept()
print("%s:%s connected to server." % client_address)
client.send(bytes("Type your name and press enter.", "utf8"))
addresses[client] = client_address
Thread(target=handle_client, args=(client,)).start()
def handle_client(client):
name = client.recv(BUFSIZ).decode("utf8")
welcome = 'Welcome %s! Type {stop} to exit.' % name
client.send(bytes(welcome, "utf8"))
msg = "%s connected to the chat!" % name
broadcast(bytes(msg, "utf8"))
clients[client] = name
while True:
msg = client.recv(BUFSIZ)
if msg != bytes("{stop}", "utf8"):
broadcast(msg, name+": ")
else:
client.send(bytes("{stop}", "utf8"))
client.close()
del clients[client]
broadcast(bytes("%s leaved the chat." % name, "utf8"))
break
def broadcast(msg, prefix=""):
for sock in clients:
sock.send(bytes(prefix, "utf8")+msg)
clients = {}
addresses = {}
HOST = '192.168.0.81'
PORT = 33000
BUFSIZ = 1024
ADDR = (HOST, PORT)
SERVER = socket(AF_INET, SOCK_STREAM)
SERVER.bind(ADDR)
if __name__ == "__main__":
SERVER.listen(5)
print("Waiting for connection...")
ACCEPT_THREAD = Thread(target=accept_incoming_connections)
ACCEPT_THREAD.start()
ACCEPT_THREAD.join()
SERVER.close()
Client.py:
from socket import AF_INET, socket, SOCK_STREAM
from threading import Thread
import tkinter
def receive():
while True:
try:
msg = client_socket.recv(BUFSIZ).decode("utf8")
msg_list.insert(tkinter.END, msg)
except OSError:
break
def send(event=None):
msg = my_msg.get()
my_msg.set("")
client_socket.send(bytes(msg, "utf8"))
if msg == "{stop}":
client_socket.close()
top.quit()
def on_closing(event=None):
my_msg.set("{stop}")
send()
top = tkinter.Tk()
top.title("Corona chat")
messages_frame = tkinter.Frame(top)
scrollbar = tkinter.Scrollbar(messages_frame)
msg_list = tkinter.Listbox(messages_frame, height=15, width=50, yscrollcommand=scrollbar.set)
scrollbar.pack(side=tkinter.RIGHT, fill=tkinter.Y)
msg_list.pack(side=tkinter.LEFT, fill=tkinter.BOTH)
msg_list.pack()
messages_frame.pack()
my_msg = tkinter.StringVar()
my_msg.set("")
entry_field = tkinter.Entry(top, textvariable=my_msg)
entry_field.bind("<Return>", send)
entry_field.pack()
send_button = tkinter.Button(top, text="Send", command=send)
send_button.pack()
top.protocol("WM_DELETE_WINDOW", on_closing)
HOST = input('Enter host: ')
PORT = input('Enter port: ')
if not PORT:
PORT = 33000
else:
PORT = int(PORT)
BUFSIZ = 1024
ADDR = (HOST, PORT)
client_socket = socket(AF_INET, SOCK_STREAM)
client_socket.connect(ADDR)
receive_thread = Thread(target=receive)
receive_thread.start()
tkinter.mainloop()