Python: ConnectionResetError: [WinError 10054] в моей программе чата при двойном соединении - PullRequest
0 голосов
/ 19 марта 2020

В настоящее время я работаю над программой чата. Я следовал учебному пособию онлайн, и в результате получился работающий чат в реальном времени.

Он состоит из файла сервера и файла клиента.

Ошибка возникает, когда я закрываю файл клиента и присоединиться к тому же экземпляру сервера. Со стороны клиента я не могу отправить сообщение. В командной строке сервера выдает эту ошибку:

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()                                                                                
...