【Python 聊天室】socket - client - server epoll

客户端测试程序 直接copy了网上弈心逐梦demon Python实现套接字(Socket)的客户端(Client)

服务器端程序使用epoll模型,参考了王辉_Pythonpython的select和epoll,加了点注释。注释参考这里:python网络编程——IO多路复用之epoll

# reference:
# https://www.cnblogs.com/JohnABC/p/6076006.html
# https://www.cnblogs.com/maociping/p/5132583.html

from socket import *
from select import *
class Socket():
    def __init__(self, host, port):
        self.host = host
        self.port = port
        self.bufsize = 1024
        self.addr = (host, port)

        self.tcpSerSock = socket(AF_INET, SOCK_STREAM)  # 创建套接字
        self.tcpSerSock.bind(self.addr) # 绑定地址和端口号
        self.tcpSerSock.listen(5) # 套接字等待链接的client个数上限是5

        self.epoll_instance = epoll()
        self.epoll_instance.register(self.tcpSerSock.fileno(),EPOLLIN|EPOLLET) 
        # 注:EPOLLIN(可读),EPOLLOUT(可写),
        # EPOLLET: 边缘触发模式(只通知一次),EPOLLLT:水平触发模式(通知后没有做处理的话还会继续通知)

        self.s_dict = {}    # 保存连接客户端编号的字典

    def accept(self):
        while True:
            self.epoll_list = self.epoll_instance.poll() # 轮询注册的事件集合,返回值为[(文件句柄,对应的事件),(...),....]
            for fd,event in self.epoll_list:
                if fd == self.tcpSerSock.fileno():  # 如果活动socket为当前服务器socket,表示有新连接
                    cs,userinfo = self.tcpSerSock.accept()
                    self.epoll_instance.register(cs.fileno(),EPOLLIN|EPOLLET)
                    self.s_dict[cs.fileno()] = cs
                else:
                    cs = self.s_dict[fd]
                    recv_data = cs.recv(1024)
                    print(recv_data.decode('UTF-8'))
                    if len(recv_data) > 0 :
                        cs.send(recv_data)
                    else:
                        print('adsfasdf')
                        self.epoll_instance.unregister(fd)
                        cs.close()
                        self.s_dict.pop(fd)


if __name__ == '__main__':
    socketx = Socket('127.0.0.1', 8080)
    socketx.accept()

猜你喜欢

转载自blog.csdn.net/m0_37946085/article/details/82948405