>source

Tkinter 라이브러리와 소켓을 사용하여 간단한 채팅을 작성하고 있습니다.

처음 서버에 연결할 때. 서버가 들어오는 메시지를 처리하고 채팅에 표시됩니다. 창을 닫고 연결을 닫는 연결 끊기 버튼을 구현하려고합니다. 클라이언트가 다시 연결할 수있는 능력이 필요합니다. 그러나 오류가 발생합니다.

Exception in thread Thread-9:
Traceback (most recent call last):
  File "user\anaconda3\lib\threading.py", line 932, in _bootstrap_inner self.run()
  File "user\anaconda3\lib\threading.py", line 870, in run self._target(*self._args, **self._kwargs)
  File "\server_.py", line 16, in listen_users send_to_users(data)
  File "\server_.py", line 10, in send_to_users user.send(data)
ConnectionAbortedError: [WinError 10053]

i Disconnect ()에서 닫는 것을 구현했습니다. 클라이언트 code :

import socket
import threading
import tkinter as tkn
sock= socket.socket(socket.AF_INET, socket.SOCK_STREAM)
message= []
def connect_to_server():
    host= adress_text.get()
    port= 49094
    sock.connect((host, port))
    while True:
        data= sock.recv(1024)
        message.append(data.decode("utf-16"))
        message_text.delete(1.0, tkn.END)
        message_text.insert(1.0, '\n'.join(message))
def send_message():
    temp_mes= name_text.get() + " : " + entry_message.get()
    temp_mes= temp_mes.encode("utf-16")
    cur_mes= temp_mes
    entry_message.delete(0, tkn.END)
    sock.send(cur_mes)
root= tkn.Tk()
connecting= threading.Thread(target= connect_to_server)
def disconnect():
    sock.shutdown(socket.SHUT_RDWR)
    sock.close()
    root.destroy()
adress_text= tkn.Entry(root, width= 20)
adress_text.insert(1, 'localhost')
adress_text.grid(row= 1, column= 0, padx= 5, pady= 5, sticky= 'w')
name_text= tkn.Entry(root, width= 20)
name_text.insert(1, 'name')
name_text.grid(row= 2, column= 0, padx= 5, pady= 5, sticky= 'w')
conn_button= tkn.Button(root, text='Connect', command=connecting.start)
conn_button.grid(row= 1, column= 1, padx= 5, pady= 5)
disconn_button= tkn.Button(root, text='Disconnect', command=disconnect)
disconn_button.grid(row= 2, column= 1, padx= 5, pady= 5)

서버 code :

import socket
import threading
server= socket.socket(socket.AF_INET, socket.SOCK_STREAM)
users= []
def send_to_users(data):
    for user in users:
        user.send(data)
def listen_users(user):
    while True:
        data= user.recv(1024)
        print(data.decode("utf-16"))
        send_to_users(data)
def run_server(host, port):
    server.bind((host, port))
    server.listen(2)
    while True:
        usr_sock, addr= server.accept()
        print(addr)
        users.append(usr_sock)
        listen_acc_user= threading.Thread(
            target= listen_users,
            args= (usr_sock,)
        )
        listen_acc_user.start()

여러 스레드에서 Tkinter에 액세스하는 것은 이상적이지 않습니다. 오류 추적을 제공하지 않고도 Tkinter가 충돌 할 수 있습니다. 또한 클라이언트가 연결 해제되면 사용자 목록에서 제거하지 마십시오. 따라서 서버는 연결이 닫혀도 데이터를 보내려고합니다. 나는 그것이 문제를 일으킬 수 있다고 생각합니다

TheLizzard2021-06-17 08:38:54
  • 이전 r : ShinyApps.IO로 외부 데이터 집합에서 실행되는 앱을 어떻게 게시합니까?
  • 다음 c++ : CPP, 문자열에서 SQLite3 DB를 만드는 방법