前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python: 玩玩EPOLL

python: 玩玩EPOLL

作者头像
超级大猪
发布2019-11-22 09:32:45
4660
发布2019-11-22 09:32:45
举报
文章被收录于专栏:大猪的笔记大猪的笔记

玩一会epoll,果然好玩

代码语言:javascript
复制
import select

import socket
import time


def svc():
    EOL1 = b'\n\n'
    EOL2 = b'\n\r\n'
    response = b'HTTP/1.0 200 OK\r\nDate: Mon, 1 Jan 1996 01:01:01 GMT\r\n'
    response += b'Content-Type: text/plain\r\nContent-Length: 13\r\n\r\n'
    response += b'Hello, world!'

    # 创建套接字对象并绑定监听端口
    serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    serversocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    serversocket.bind(('0.0.0.0', 8080))
    serversocket.listen(1)
    serversocket.setblocking(0)

    # 创建epoll对象,并注册socket对象的 epoll可读事件
    epoll = select.epoll()
    epoll.register(serversocket.fileno(), select.EPOLLIN|select.EPOLLET)

    try:
        connections = {}
        requests = {}
        responses = {}
        while True:
            time.sleep(0.1)
            # 主循环,epoll的系统调用,一旦有网络IO事件发生,poll调用返回。这是和select系统调用的关键区别
            events = epoll.poll(1)
            # 通过事件通知获得监听的文件描述符,进而处理
            for fileno, event in events:
                print("event {}".format(event))
                # 注册监听的socket对象可读,获取连接,并注册连接的可读事件
                if fileno == serversocket.fileno():
                    print("start accept fileno {}".format(fileno))
                    connection, address = serversocket.accept()
                    connection.setblocking(0)
                    epoll.register(connection.fileno(), select.EPOLLIN|select.EPOLLET)
                    connections[connection.fileno()] = connection
                    requests[connection.fileno()] = b''
                    responses[connection.fileno()] = response
                elif event & select.EPOLLIN:
                    # 连接对象可读,处理客户端发生的信息,并注册连接对象可写
                    msg = connections[fileno].recv(1)
                    print("fileno {}, rec: {}".format(fileno, msg))
                    requests[fileno] += msg
                    if msg == b'':
                        epoll.modify(fileno, 0)
                        connections[fileno].shutdown(socket.SHUT_RDWR)

                    if EOL1 in requests[fileno] or EOL2 in requests[fileno]:
                        epoll.modify(fileno, select.EPOLLOUT)
                        print('-' * 40 + '\n' + requests[fileno].decode()[:-2])
                elif event & select.EPOLLOUT:
                    print("select.EPOLLOUT start")
                    # 连接对象可写事件发生,发送数据到客户端
                    byteswritten = connections[fileno].send(responses[fileno])
                    responses[fileno] = responses[fileno][byteswritten:]
                    if len(responses[fileno]) == 0:
                        epoll.modify(fileno, 0)
                        connections[fileno].shutdown(socket.SHUT_RDWR)
                elif event & select.EPOLLHUP or event & (select.EPOLLIN
                                                             | select.EPOLLRDHUP):
                    print("select.EPOLLHUP start")
                    epoll.unregister(fileno)
                    connections[fileno].close()
                    del connections[fileno]
    finally:
        epoll.unregister(serversocket.fileno())
        epoll.close()
        serversocket.close()
        serversocket.close()


def cli():
    host = "localhost"
    port = 8164
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((host, port))
    try:
        while 1:
            msg = input()
            if msg == 'close':
                s.close()
                return
            s.send(msg.encode())

            # print(s.recv(1024))
    finally:
        s.close()


# svc()
# cli()
import sys

print(sys.argv)
if sys.argv[1] == 'cli':
    cli()
else:
    svc()
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-09-07 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档