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)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix