即使所有客户端都断开连接,我的Python异步服务器也不会停止

问题描述 投票:0回答:1

如果客户端已连接,即使客户端关闭套接字,我的异步服务器也不会关闭。为什么不停止呢?如果客户端在 10 秒内未连接,它将关闭并且程序关闭。

我的程序:

  • 运行服务器.py
  • 运行 client.py - 客户端连接并立即关闭套接字。

结果:

  • 服务器挂起并且无法关闭
# server
from os import path as ospath
import asyncio
import socket as Socket
import logger as log

logger = log.getLogger(fileName=ospath.join('log', 'server.log'), initialize=True)

class Client():
    def __init__(self, socket:Socket=None, addr:tuple=None) -> None:
        self.socket = socket
        self.addr = addr
        self.connected = False

class App():
    def __init__(self) -> None:
        self.quit = False
        self.clients = []

async def clientHandler(reader, writer):
    logger.info('client handler starting')

async def main():
    logger.info("server app starting")
    app = App()
    
    # start socket server
    ipaddr = Socket.gethostbyname(Socket.gethostname())
    port = 32843
    logger.info(f'starting socket server ({ipaddr}:{port})')
    server = await asyncio.start_server(clientHandler, ipaddr, port=32843)

    logger.info('waiting for client to connect...')
    await asyncio.sleep(10)
    logger.info('closing server')
    server.close()

    await server.wait_closed()
    logger.info('server closed')

if __name__ == '__main__':
    asyncio.run(main())
# client
import socket

dest_ip = socket.gethostbyname(socket.gethostname())
dest_port = 32843
encoder = "utf-8"

client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect((dest_ip, dest_port))

client_socket.shutdown(socket.SHUT_RDWR)
client_socket.close()
python python-3.x sockets python-asyncio python-3.12
1个回答
0
投票

您遇到的问题是由于客户端连接时

clientHandler
协程未正确退出。当客户端连接时,
clientHandler
启动,但由于它不包含任何会导致其退出或处理连接的代码,因此它会无限期地运行。这可以防止服务器关闭,因为
asyncio.run()
会等待所有正在运行的任务完成后再退出。

要解决此问题,您需要确保

clientHandler
在处理客户端连接后正确退出。以下是修改代码的方法:

async def clientHandler(reader, writer):
    logger.info('client handler starting')
    try:
        while True:
            data = await reader.read(1024)
            if not data:
                # No more data from client, connection is closed
                break
            # Process data (if needed)
            logger.info(f"Received data: {data}")
    except Exception as e:
        logger.error(f"Error in client handler: {e}")
    finally:
        logger.info('client handler closing')
        writer.close()
        await writer.wait_closed()
© www.soinside.com 2019 - 2024. All rights reserved.