python epoll socket 事件

最近想实现一个关于socket长连接但是一个服务端只能实现一个链接,这可怎么办呢???????

基于多线程实现

自己写的垃圾框架 贼垃圾

第一开始的时候我想用async协程去实现
因为用多线程的话真的觉得不合适,因为我现在写的这个项目是需要和N多个设备进行长连接的,就不断开了!
这.....万一来了N个客户端,岂不是N+1个线程。这可不行啊
基于async实现的思路
其实我还没撸出来基于async的代码但是我已经想好了。我在这里说明一下
1.阻塞都在哪里进行阻塞  accept 阻塞等待新的客户端,以及等待老的客户端recv消息

我也不知道我的思路对不对,我先说一下 过几天我就亲自实现一下然后将代码奉上

socket还是作为全局对象,然后还是老样子创建一个客户端的容器用来存放用户端
紧接着创建一个携程函数,里面while这监听,同样创建一个携程函数一直监听收消息
在创建一个携程函数用来await一下收消息的函数,创建main函数将监听用户注册到loop事件循环中
我也不知道对不对,过几天实现来验证吧。

基于epoll实现

说一下关于epoll实现的
	系统分为用户态和内核态  下面是自己最通俗理解的不知道准确与否 欢迎指点
	用户态:你自己的程序在没有操作操作系统的内东西的时候
	内核态:操作系统

如果socket让操作系统去监听有没有人去链接你呢? 有人链接你的时候操作系统来告诉你有人链接你了,可以处理了
这样循环的时候并不是你自己的程序进行循环,而是操作系统

同步与异步的IO操作

同步
import time


def long_io():
    print("开始执行耗时操作")
    time.sleep(2)
    print("完成执行耗时操作")
    result = 'io result'
    return result


def work1():
    print(" 开始处理work1请求操作 ")
    ret = long_io()
    print(ret)
    print('完成处理work1请求')


def work2():
    print("开始处理work2")
    print("处理work2请求完成")


def main():
    work1()
    work2()


if __name__ == '__main__':
    main()
异步
import time
from threading import Thread


def long_io(cb):
    def fun(callback):
        print("开始执行耗时操作")
        time.sleep(3)
        print("完成执行耗时操作")
        result = 'io result'
        callback(result)
        return "123"

    thread = Thread(target=fun, args=(cb,))
    thread.start()


def on_finish(ret):
    print("1231231231")
    print(ret)
    print("1231231231")


def work1():
    print(" 开始处理work1请求操作 ")
    ret = long_io(on_finish)
    print(ret)
    print('完成处理work1请求')


def work2():
    print("开始处理work2")
    # time.sleep(2)
    print("处理work2请求完成")


def main():
    work1()
    work2()



if __name__ == '__main__':
    main()
IO多路复用模型

在这里插入图片描述

反正就是将耗时操作交给系统处理吧 主程序处理主程序应该处理的问题 至于原理的话本人只知道个理解
并不能进行教学 有兴趣的话自行百度
参阅python的文档
# select
import selectors
# socket
import socket
# time
import time
# 线程
import threading
from threading import Thread

server = socket.socket()
server.bind(("0.0.0.0", 8200))
server.listen(5)
epoll = selectors.EpollSelector()
# 客户端存放
server_lst = []


def new_func(conn):
   data = conn.recv(1024)
   if data == b'':
   	   #删除轮训对象正在跟踪的文件描述符
       epoll.unregister(conn)
       conn.colse()
   else:
       print("收到的数据是:%s" % data.decode())
       conn.send(data)


def func(ser):
	   conn, addr = ser.accept()
	   global server_lst
	   server_lst.append(conn)
	   print("来了一个链接")
	   # 查看是否有数据
	   print(server_lst)
	   # 将此对象注册到epoll中,最后一个则是事件对象第二个是事件类型
	   epoll.register(conn, selectors.EVENT_READ, new_func)


def main():
   time.sleep(1)
   # 将socket注册 要是来链接后唤醒
   epoll.register(server, selectors.EVENT_READ, func)

   while True:
   		# 实例化注册文件列表
       events = epoll.select()
       # 循环注册文件列表 key是文件对象的实例化,而mask则是事件位掩码
       for key, mask in events:
       		# 实例化回调函数
           callback = key.data
           将已注册的文件对象拿出来
           sock = key.fileobj
			# 运行回调方法
           callback(sock)

# 主程序创建辅助线程去管理
thread = Thread(target=main)
thread.setDaemon(True)
thread.setName("辅助线程")
thread.start()
# 主程序逻辑
while True:
   num = input("请输入:")
   _ = {
       "1": lambda: print(server_lst),
       "2": lambda: print(threading.enumerate()),
   }.get(num, None)()
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值