栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

python 使用tcp协议实现web服务器(七) epoll版本web服务器

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

python 使用tcp协议实现web服务器(七) epoll版本web服务器

文章目录
      • 摘要
      • 前置知识
      • 运行截图
      • html,css文件代码
        • index.html
        • https://blog.csdn.net/a_123_4/article/details/login.html
        • https://blog.csdn.net/a_123_4/article/details/register.html
        • style.css
      • python代码

摘要

使用python 基于tcp协议开发http web服务器(六)。这个版本没有使用多进程、多线程,因为当请求量特别多的时候,使用epoll才是效率更高的,具体效果如下。

在放置该python代码文件的目录下,创建index.html、https://blog.csdn.net/a_123_4/article/details/login.html、https://blog.csdn.net/a_123_4/article/details/register.html、style.css这几个文件,文件内容在下面。要保证与python代码文件在同一目录下
如图:

前置知识

这些都是一些基础知识,论坛里面都有写的很好的教程。

  • tcp协议
  • socket
  • http协议请求格式、响应格式
  • epoll
运行截图

服务器

访问存在文件


访问不存在文件

html,css文件代码

注:需要与python代码文件处于同一级别目录

index.html



    
    首页
    


    

这是首页

前往注册

前往登录

https://blog.csdn.net/a_123_4/article/details/login.html



    
    登录
    


    登录页面
    

账号:

密码:

下次自动登录

注册

https://blog.csdn.net/a_123_4/article/details/register.html



    
    注册
    


    注册页面
    

账号:

密码:

登录

style.css
*{margin: 5px;}
form{background-color: cadetblue;width: 260px;}
.left{float: right;}
button{width: 50%;}
python代码
import socket
import select
from datetime import datetime


def response_handler(client_socket, recv_data):
    """响应处理相关实现"""
    # 等待客户端发送数据请求
    # recv_data = client_socket.recv(1024)
    # 解码请求头
    request_headers = recv_data.decode("utf-8")
    request_headers_l = request_headers.splitlines()
    # 打印请求信息
    print("{} -->".format(datetime.now()), request_headers_l[0])
    # 提取出访问资源    GET /index.html HTTP/1.1
    source = request_headers_l[0].split(' ')[1]
    if source == "/":
        # 默认设置为index.html
        source = "/index.html"

    # 读取资源文件,并发送给客户端
    try:
        # 打开文件
        file = open(".{}".format(source), "rb")
    except FileNotFoundError:
        # 文件不存在,返回404
        print("404 Not Found ==>", source)
        # 响应体
        response_body = "

404,文件找不到!" # 生成响应头 response_headers = "HTTP/1.1 404 Not Foundrncontent-type: text/html; charset=utf-8rn" # 响应头添加Content-Length response_headers += "Content-Length: %drn" % len(response_body) response = response_headers + "rn" + response_body # 发送给客户端 client_socket.send(response.encode("utf-8")) else: # 读取文件内容 file_content = file.read() file.close() response_body = file_content response_headers = "HTTP/1.1 200 OKrncontent-type: text/html; charset=utf-8rn" # 如果是请求css文件,响应头要加上这个,浏览器才能解析 if source[-3:] == "css": response_headers = "HTTP/1.1 200 OKrncontent-type: text/cssrn" # 响应头添加Content-Length response_headers += "Content-Length: %drn" % len(response_body) # 空白行,分割出响应头和响应体 response_headers += "rn" response = response_headers.encode("utf-8") + response_body # 发给客户端 client_socket.send(response) # 长连接, 不用关闭了 # 关闭套接字连接 # client_socket.close() def http_service(): """http服务实现""" # 创建tcp套接字 tcp_service_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) tcp_service_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 绑定ip和端口 ip = "127.0.0.1" port = 8080 bind = (ip, port) tcp_service_socket.bind(bind) print("服务器地址:http://{}:{}".format(ip, port)) # 转为监听 tcp_service_socket.listen(124) # 创建epoll对象 epoll = select.epoll() # 将服务端套接字对象的文件描述符注册到epoll中, 第二个参数为监听类型,in为接收到 epoll.register(tcp_service_socket.fileno(), select.EPOLLIN) # 存储与连接的客户端套接字, key为套接字对象的文件描述符, value为套接字对象 client_socket_dict = dict() while True: # 阻塞等待操作系统通知,事件通知(有客户端连接或者客户端发送数据过来是解阻塞) # 返回一个事件列表,列表的每个元祖代表一个事件,元祖第一个值是文件描述符号,第二个值是事件类型 fd_event_list = epoll.poll() for fd, event in fd_event_list: # fd是套接字对象对应的文件描述符,event是触发的事件 if fd == tcp_service_socket.fileno(): # 事件通知中的文件描述符与服务端套接字相同,说明是新客户连接了被触发 client_socket, client_addr = tcp_service_socket.accept() # 将新套接字注册到epoll中,选择一样的监听模式 epoll.register(client_socket, select.EPOLLIN) # 套套接字存入到字典中 client_socket_dict[client_socket.fileno()] = client_socket elif event == select.EPOLLIN: # 其余的事件都是客户端发送请求过来 # 从字典中取出套接字对象 client_socket = client_socket_dict[fd] data = client_socket.recv(1024) if data: # 发送了数据, data不是None, 进一步处理 response_handler(client_socket, data) else: # 客户端断开了连接,从字典中删除,取消注册 client_socket.close() del client_socket_dict[fd] epoll.unregister(fd) def main(): # 调用函数,开启http服务 http_service() if __name__ == "__main__": main()

建了一个python交流群,要是大家有疑问或者想交流的,欢迎进群交流,QQ群号码:891938703

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/950011.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号