python聊天室day1

目录

    参考了smallchat的思路,准备实现一个使用epoll模型的io
    ok了,epoll模型没法在windows上面实现,gg
    先使用select模型吧
    这里是当前使用select模型的代码,后续补充线程池负责处理和客户端的通信

    #!/usr/bin/python
    # -*- coding: UTF-8 -*-
    # 文件名:server.py
    import select
    
    import socket  # 导入 socket 模块
    
    import time
    
    import string
    
    # 创建端口和客户端最大数量
    SERVER_PORT = 55555
    MAX_CLIENTS = 8192
    
    
    # 定义客户端,有一个昵称和fd
    class Client:
        def __init__(self, Socket,Addr, Nick="Anonymous"):
            self.Sock = Socket
            # 默认是匿名
            self.Nick = Nick
            # addr
            self.Address=Addr
    
    
    # 定义服务器
    class Server:
        def __init__(self):
            # 服务器socket
            self.ServerSock = -1
            # 客户端数量
            self.NumberOfClient = 0
            # 当前客户端Socket信息
            self.Clients = {}
    
    
    # 绑定并监听
    def CreateTCPServer(Port):
        try:
            #TCP ipv4
            Sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            #reuse端口
            Sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            Host = socket.gethostname()
            Sock.bind((Host, Port)) 
            Sock.listen(10)
        except socket.error as e:
            print("CreateTCPServer发生异常",e)
            socket.close(Sock)
            exit(0)
        return Sock
    
    
    # 接受新连接
    def AcceptClient(Sock):
        try:
            ClientSocket, ClientAddress = Sock.accept()
            print("Client connect: ", ClientAddress)
        except (socket.error, socket.timeout) as e:
            print("accept error: ", e)
    
        return ClientSocket,ClientAddress
    
    
    # 创建客户端实例
    def CreateNewClient(ClientSock,ClientAddr):
        # 非阻塞IO
        ClientSock.setblocking(False)
        # 实例化client对象
        client = Client(ClientSock,ClientAddr)
        # Server设置
        ServerInstance.NumberOfClient += 1
        # print(Clientfd.fileno())
        ServerInstance.Clients[ClientSock]=client
    
        return client
    
    
    def RemoveSockFromServer(Sock):
        ServerInstance.NumberOfClient -= 1
        del ServerInstance.Clients[Sock]
        Sock.close()
    
    
    def SendMsgExcept(ExcludedSock, Message):
        for Sock,client in ServerInstance.Clients.items():
            if Sock == ExcludedSock:
                continue
            client.Sock.send(Message)
    
    
    # 主逻辑
    ServerInstance = Server()
    ServerInstance.ServerSock = CreateTCPServer(SERVER_PORT)
    
    if ServerInstance.ServerSock == -1:
        raise Exception("Create TCP Server Failed...\n")
    
    while True:
        ReadSet = []
        WriteSet = []
        ExceptionSet = []
    
        # 将fd加入读集合
        for Sock in ServerInstance.Clients:
            ReadSet.append(Sock)
            print(Sock)
    
        ReadSet.append(ServerInstance.ServerSock)
    
       # for Sock in ReadSet:
            #print(Sock)
    
        print("SELECT IO READY")
    
        ReadSet, WriteSet, ExceptionSet = select.select(ReadSet, WriteSet, ExceptionSet)
    
        print("SELECT IO FINISH")
    
        # 遍历读集合
        for ReadSock in ReadSet:
            if ReadSock == ServerInstance.ServerSock:
                ClientSock,ClientAddr = AcceptClient(ServerInstance.ServerSock)
                ClientInstance = CreateNewClient(ClientSock,ClientAddr)
                HelloMessage = """
                    Hello user, Welcome to Python chatroom
                    print /nick yournick to change your nick
                """
                ClientInstance.Sock.send(HelloMessage)
                #print("New client fd: ", Clientfd)
            else:
                MessageFromClient = ReadSock.recv(1024)
                print(MessageFromClient)
                if not MessageFromClient:
                    # 连接已断开了
                    print(ReadSock, "Connection close1")
                    RemoveSockFromServer(ReadSock)
                else:
                    client = ServerInstance.Clients[ReadSock]
                    #print(client)
                    if MessageFromClient[0] == "/":
                        if MessageFromClient.find("nick") == 1:
                            NickName = MessageFromClient.split(" ", 1)[1]
                            client.nick = NickName
                        else:
                            ReadSock.send("Unsupported command")
                    else:
                        MessageToClient = "{}> {}".format(client.Nick, MessageFromClient)
                        SendMsgExcept(ReadSock, MessageToClient)
    
    
    posted @   LiviaYu  阅读(8)  评论(0编辑  收藏  举报
    相关博文:
    阅读排行:
    · Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
    · 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
    · 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
    · 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
    · 【自荐】一款简洁、开源的在线白板工具 Drawnix
    点击右上角即可分享
    微信分享提示