当前位置: 首页 > news >正文

网络应用之静态Web服务器

静态Web服务器-返回固定页面数据

学习目标

  • 能够写出组装固定页面数据的响应报文


1. 开发自己的静态Web服务器

实现步骤:

  1. 编写一个TCP服务端程序

  1. 获取浏览器发送的http请求报文数据

  1. 读取固定页面数据,把页面数据组装成HTTP响应报文数据发送给浏览器。

  1. HTTP响应报文数据发送完成以后,关闭服务于客户端的套接字。

2. 静态Web服务器-返回固定页面数据的示例代码

import socketif __name__ == '__main__':# 创建tcp服务端套接字tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 设置端口号复用, 程序退出端口立即释放tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)# 绑定端口号tcp_server_socket.bind(("", 9000))# 设置监听tcp_server_socket.listen(128)whileTrue:# 等待接受客户端的连接请求new_socket, ip_port = tcp_server_socket.accept()# 代码执行到此,说明连接建立成功recv_client_data = new_socket.recv(4096)# 对二进制数据进行解码recv_client_content = recv_client_data.decode("utf-8")print(recv_client_content)with open("static/index.html", "rb") as file:# 读取文件数据file_data = file.read()# 响应行response_line = "HTTP/1.1 200 OK\r\n"# 响应头response_header = "Server: PWS1.0\r\n"# 响应体response_body = file_data# 拼接响应报文response_data = (response_line + response_header + "\r\n").encode("utf-8") + response_body# 发送数据new_socket.send(response_data)# 关闭服务与客户端的套接字new_socket.close()

3. 小结

  1. 编写一个TCP服务端程序

tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 循环接受客户端的连接请求whileTrue:conn_socket, ip_port = tcp_server_socket.accept()
  1. 获取浏览器发送的http请求报文数据

client_request_data = conn_socket.recv(4096)
  1. 读取固定页面数据,把页面数据组装成HTTP响应报文数据发送给浏览器。

response_data = (response_line + response_header + "\r\n").encode("utf-8") + response_body
conn_socket.send(response_data)
  1. HTTP响应报文数据发送完成以后,关闭服务于客户端的套接字。

conn_socket.close()

静态Web服务器-返回指定页面数据

学习目标

  • 能够写出组装指定页面数据的响应报文


1. 静态Web服务器的问题

目前的Web服务器,不管用户访问什么页面,返回的都是固定页面的数据,接下来需要根据用户的请求返回指定页面的数据

返回指定页面数据的实现步骤:

  1. 获取用户请求资源的路径

  1. 根据请求资源的路径,读取指定文件的数据

  1. 组装指定文件数据的响应报文,发送给浏览器

  1. 判断请求的文件在服务端不存在,组装404状态的响应报文,发送给浏览器

2. 静态Web服务器-返回指定页面数据的示例代码

import socketdefmain():# 创建tcp服务端套接字tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 设置端口号复用, 程序退出端口立即释放tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)# 绑定端口号tcp_server_socket.bind(("", 9000))# 设置监听tcp_server_socket.listen(128)whileTrue:# 等待接受客户端的连接请求new_socket, ip_port = tcp_server_socket.accept()# 代码执行到此,说明连接建立成功recv_client_data = new_socket.recv(4096)if len(recv_client_data) == 0:print("关闭浏览器了")new_socket.close()return# 对二进制数据进行解码recv_client_content = recv_client_data.decode("utf-8")print(recv_client_content)# 根据指定字符串进行分割, 最大分割次数指定2request_list = recv_client_content.split(" ", maxsplit=2)# 获取请求资源路径request_path = request_list[1]print(request_path)# 判断请求的是否是根目录,如果条件成立,指定首页数据返回if request_path == "/":request_path = "/index.html"try:# 动态打开指定文件with open("static" + request_path, "rb") as file:# 读取文件数据file_data = file.read()except Exception as e:# 请求资源不存在,返回404数据# 响应行response_line = "HTTP/1.1 404 Not Found\r\n"# 响应头response_header = "Server: PWS1.0\r\n"with open("static/error.html", "rb") as file:file_data = file.read()# 响应体response_body = file_data# 拼接响应报文response_data = (response_line + response_header + "\r\n").encode("utf-8") + response_body# 发送数据new_socket.send(response_data)else:# 响应行response_line = "HTTP/1.1 200 OK\r\n"# 响应头response_header = "Server: PWS1.0\r\n"# 响应体response_body = file_data# 拼接响应报文response_data = (response_line + response_header + "\r\n").encode("utf-8") + response_body# 发送数据new_socket.send(response_data)finally:# 关闭服务与客户端的套接字new_socket.close()if __name__ == '__main__':main()

3. 小结

  1. 获取用户请求资源的路径

 request_list = client_request_conent.split(” ”,  maxsplit=2)request_path = request_list[1]
  1. 根据请求资源的路径,读取请求指定文件的数据

with open("static" + request_path, "rb") as file:file_data = file.read()
  1. 组装指定文件数据的响应报文,发送给浏览器

 response_data = (response_line + response_header + "\r\n").encode("utf-8") + response_bodyconn_socket.send(response_data)
  1. 判断请求的文件在服务端不存在,组装404状态的响应报文,发送给浏览器

try:# 打开指定文件,代码省略...except Exception as e:conn_socket.send(404响应报文数据)

相关文章:

网络应用之静态Web服务器

静态Web服务器-返回固定页面数据学习目标能够写出组装固定页面数据的响应报文1. 开发自己的静态Web服务器实现步骤:编写一个TCP服务端程序获取浏览器发送的http请求报文数据读取固定页面数据,把页面数据组装成HTTP响应报文数据发送给浏览器。HTTP响应报文数据发送完…...

IndexDB 浏览器服务器

IndexDB 浏览器服务器 文章部分内容引用: https://www.ruanyifeng.com/blog/2018/07/indexeddb.html https://juejin.cn/post/7026900352968425486#heading-15 基本概念 数据库:IDBDatabase 对象对象仓库:IDBObjectStore 对象索引&#xff1…...

追梦之旅【数据结构篇】——详解C语言实现链队列

详解C语言实现链队列~😎前言🙌整体实现内容分析💞预备小知识🙌1.链队列头文件编写🙌2.链队列功能文件(Queue.c )编写:🙌1)初始化函数实现2)销毁函…...

SpringMVC - 13 - SpringMVC执行流程

文章目录1、SpringMVC常用组件2、DispatcherServlet初始化过程a>初始化WebApplicationContextb>创建WebApplicationContextc>DispatcherServlet初始化策略3、DispatcherServlet调用组件处理请求a>processRequest()b>doService()c>doDispatch()d>processDi…...

6091: 斐波那契数列

描述一个斐波那契序列,F(0) 0, F(1) 1, F(n) F(n-1) F(n-2) (n>2),根据n的值,计算斐波那契数F(n)。输入输入数据的第一行为测试用例的个数t,接下来为t行,每行为一个整数n(2≤n≤40)。输出…...

任何人均可上手的数据库与API搭建平台

编写API可能对于很多后端开发人员来说,并不是什么难事儿,但如果您主要从事前端功能,那么可能还是有一些门槛。 那么有没有工具可以帮助我们降低编写API的学习门槛和复杂度呢? 今天就来给大家推荐一个不错的开源工具:…...

Ubuntu(虚拟机)的Anaconda 及使用

安装Anaconda 使用firefox打开Ananconda网址Anaconda | The Worlds Most Popular Data Science Platform 下载后有.sh文件: Anaconda3-2022.10-Linux-x86_64.sh 进入所在目录打开终端并输入 $ bash Anaconda3-2022.10-Linux-x86_64.sh 然后开始安装。 对于给…...

Git ---- IDEA集成 GitHub

Git ---- IDEA集成 GitHub1. 设置 GitHub 账号2. 分享工程到 GitHub3. push 推送本地库到远程库4. pull 拉取远程库到本地库5. clone 克隆远程库到本地1. 设置 GitHub 账号 新版的 IDEA 选择之后会自动登录,就不需要设置 token 了。 如果是老版的 IDEA 的话&…...

opencv提取结构化文本总结

扫描文件表格识别 1.识别结构 situation1 有明确表格结构 1.纠正表格偏移角度(获取最大轮廓,计算最小的矩形,变换坐标截取矩形) 获取面积最大轮廓 _, contours, HIERARCHY cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2…...

JVM知识体系学习八:OOM的案例(承接上篇博文,可以作为面试中的案例)

文章目录前言一、概述二、案例二三、案例:方法区内存溢出1、代码:LambdaGC.java2、元空间内存溢出日志3、分析4、疑问*****四、案例:直接内存溢出问题(少见)(尽量不说)五、案例:栈内存溢出问题1…...

Redis的持久化方式

Redis支持两种方式的持久化,一种是RDB方式、另一种是AOF(append-only-file)方式,两种持久化方式可以单独使用其中一种,也可以将这两种方式结合使用。 •RDB:根据指定的规则“定时”将内存中的数据存储在硬…...

【unity游戏制作-mango的冒险】-4.场景二的镜头和法球特效跟随

👨‍💻个人主页:元宇宙-秩沅 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 本文由 秩沅 原创 收录于专栏:unity游戏制作 ⭐mango的冒险场景二——镜头和法球特效跟随⭐ 文章目录⭐mango的冒险场景二——镜…...

handwrite-1

-------------------- 实现防抖函数(debounce) 防抖函数原理:把触发非常频繁的事件合并成一次去执行 在指定时间内只执行一次回调函数,如果在指定的时间内又触发了该事件,则回调函数的执行时间会基于此刻重新开始计算…...

【一天一门编程语言】Pascal 语言程序设计极简教程

Pascal 语言程序设计极简教程 用 markdown 格式输出答案。 不少于3000字。细分到2级目录。 文章目录 Pascal 语言程序设计极简教程一、Pascal简介1.1 Pascal历史1.2 Pascal的特点1.3 Pascal的应用二、Pascal语言程序设计2.1 Pascal编程环境2.2 Pascal的基本语法2.3 Pascal程序…...

【基础篇0】Linux下ANACONDA与TF-LITE环境配置

0 写在前面:一些摸索与总结 对于Linux系统,我发现不管是电脑x86的Ubuntu还是树莓派arm的raspberry系统,在系统安装完毕后,总是自带一个特定版本的python.   例如我的ubuntu22.04自带的python版本是3.10,而高版本的py…...

TCP协议原理二

文章目录四、滑动窗口二、流量窗口三、拥塞控制四、滑动窗口 前面我们学习了 确认应答,超时重传,连接管理,这些机制都为我们TCP的可靠性提供了保证,当然在保证TCP的可靠性的同时,传输效率也受到了一定的影响&#xff…...

电子科技大学网络协议(TCP/IP作业答案)--网工(五次作业汇总)

目录 作业1:OSI/RM、TCP/IP编址和底层网络技术 作业2:IP地址规划与路由选择 作业3:ARP、IP、ICMP 作业4:UDP、Routing Protocol 作业五 作业1:OSI/RM、TCP/IP编址和底层网络技术 物理地址属于OSI/RM的哪一层&…...

Kubernetes集群声明式文件YAML

一、YAML介绍 YAML 的意思是:仍是一种标记语言,但为了强调这种语言以数据做为中心,而不是以标记语言为重点。是一个可读性高,用来表达数据序列的格式。 二、基本语法 1.低版本缩进时不允许使用Tab键,只允许使用空格…...

为赋能,创共赢~ 〖TFS_CLUB社区〗-〖星荐官计划〗来袭~ 期待各位小伙伴的加入~

文章目录❤️‍🔥 TFS社区介绍❤️‍🔥 星荐官计划在直播结束之后,有几位小伙伴跟我说,想法是好的,但是会很难搞。试想一下如果真的是很容易做的事情,那岂不是人人都可以做?正因为难做&#xff…...

【华为OD机试模拟题】用 C++ 实现 - 水仙花数(2023.Q1)

最近更新的博客 【华为OD机试模拟题】用 C++ 实现 - 获得完美走位(2023.Q1) 文章目录 最近更新的博客使用说明水仙花数题目输入输出描述示例一输入输出说明示例二输入输出Code使用说明 参加华为od机试,一定要注意不要完全背诵代码,需要理解之后模仿写出,通过率才会高。…...

19c补丁后oracle属主变化,导致不能识别磁盘组

补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...

7.4.分块查找

一.分块查找的算法思想: 1.实例: 以上述图片的顺序表为例, 该顺序表的数据元素从整体来看是乱序的,但如果把这些数据元素分成一块一块的小区间, 第一个区间[0,1]索引上的数据元素都是小于等于10的, 第二…...

ubuntu搭建nfs服务centos挂载访问

在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...

【C语言练习】080. 使用C语言实现简单的数据库操作

080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

MySQL 8.0 OCP 英文题库解析(十三)

Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

Pinocchio 库详解及其在足式机器人上的应用

Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖

在Vuzix M400 AR智能眼镜的助力下,卢森堡罗伯特舒曼医院(the Robert Schuman Hospitals, HRS)凭借在无菌制剂生产流程中引入增强现实技术(AR)创新项目,荣获了2024年6月7日由卢森堡医院药剂师协会&#xff0…...

渗透实战PortSwigger靶场:lab13存储型DOM XSS详解

进来是需要留言的&#xff0c;先用做简单的 html 标签测试 发现面的</h1>不见了 数据包中找到了一个loadCommentsWithVulnerableEscapeHtml.js 他是把用户输入的<>进行 html 编码&#xff0c;输入的<>当成字符串处理回显到页面中&#xff0c;看来只是把用户输…...

6️⃣Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙

Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙 一、前言:离区块链还有多远? 区块链听起来可能遥不可及,似乎是只有密码学专家和资深工程师才能涉足的领域。但事实上,构建一个区块链的核心并不复杂,尤其当你已经掌握了一门系统编程语言,比如 Go。 要真正理解区…...

32单片机——基本定时器

STM32F103有众多的定时器&#xff0c;其中包括2个基本定时器&#xff08;TIM6和TIM7&#xff09;、4个通用定时器&#xff08;TIM2~TIM5&#xff09;、2个高级控制定时器&#xff08;TIM1和TIM8&#xff09;&#xff0c;这些定时器彼此完全独立&#xff0c;不共享任何资源 1、定…...