如何发送请求从服务器断开连接到所有客户端和服务器仍然存在(python套接字)

How to send request disconnect from server to all clients and server still live (python socket)

当我断开服务器中所有客户端的连接时,服务器无法继续运行。我怎样才能为生活服务器做

import socket, threading, tkinter

服务器

import socket, threading, tkinter
import time

def sendDisconnectAll(my_clients):
    for client in my_clients:
        conn = client[0]
        conn.sendall('Disconnect'.encode('utf8'))
        conn.close()
    
def handle_client(conn, addr):
    while True:
        try:
            request_from_clients = conn.recv(1024).decode('utf8') #sample request
            print(request_from_clients)
            if request_from_clients == 'SignIn':
                conn.sendall('Accept Sign in'.encode('utf8'))
        except:
            print('Client has been shutdown')
            break

my_clients = []
def live_server():
    global thr
    global s
    while True:
        try:
            conn, addr = s.accept()
            my_clients.append((conn, addr))
            thr = threading.Thread(target=handle_client, args=(conn, addr))
            thr.daemon = True
            thr.start()
        except:
            print("Error")

HOST = '127.0.0.1'
PORT = 8000
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen()
print('HOST: ', HOST)
print('PORT: ', PORT)

thr = threading.Thread(target=live_server)
thr.daemon = True
thr.start()
count_time = time.time()
while True:
    now = time.time()
    if (int(now - count_time) + 1) % 10 == 0:       #Disconnect all clients after 10 seconds
        count_time = now
        request = 'Disconnect'
        print('Disconnect all')
        sendDisconnectAll(my_clients)

客户

import socket, threading
import tkinter as tk
from tkinter import *

def signIn():
    global client
    request = 'SignIn'
    try:
        client.sendall(request.encode('utf8'))
        client.recv(1024).decode('utf8')
    except:
        print('Server has been shutdown')

IP = input("Enter IP: ")
PORT = input("Enter PORT: ")

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

try:
    client.connect((IP, int(PORT)))
except:
    print("Can't connect to server")
    client.close()
def live_client():
    global client
    while True:
        print(client.recv(1024).decode('utf8'))
thr = threading.Thread(target=live_client)
thr.daemon = True
thr.start()
app = Tk()
app.title('CLIENT')
but_connect = tk.Button(app, text="SIGN IN",
                            width=20, command=signIn)
but_connect.pack(pady=6)
app.mainloop()

谢谢!

问题是您只将客户端添加到 my_clients 列表中。让我们看看服务器中发生了什么:

  • 服务器启动
  • 它收到一个客户并将其添加到 my_clients
  • 在下一个 断开所有连接 操作时,该客户端的套接字已关闭,但该客户端仍在列表中
  • 在接下来的 disconnect all 操作中,服务器的主线程尝试写入已关闭的套接字并引发异常
  • 由于所有其他线程都是守护进程,应用程序结束。

您必须在关闭所有客户端套接字后清除 my_clients 列表:

def sendDisconnectAll(my_clients):
    for client in my_clients:
        conn = client[0]
        conn.sendall('Disconnect'.encode('utf8'))
        conn.close()
    my_clients.clear()

注意:我没有查看客户端代码...