老男孩python学习自修第二十一天【socket】
1. 使用python编写一个静态的web服务器,能够处理静态页面的http请求
原理:
a. 使用socket进行服务端和浏览器之间的通信
b. 使用多线程处理多个客户端浏览器的请求
c. 解析用户请求并使用http协议发送响应数据
实现:
# coding:UTF-8
import socket
import re
from multiprocessing import Process
def handle_request(client_socket):
# 定义html服务器根目录
HTML_ROOT_DIR = "./html"
# 接收用户的请求
request_data = client_socket.recv(1024)
# 解析用户的请求
request_lines = request_data.splitlines()
request_first_line = request_lines[0].decode("UTF-8")
# 使用正则表达式取出请求的文件名
file_name = re.match(r"\w+ +(/[^ ]*) ", request_first_line).group(1)
# 默认请求的文件名为index.html
if "/" == file_name:
file_name = "/index.html"
file_path = HTML_ROOT_DIR + file_name
# 读取请求资源的内容, 并构造响应报文
try:
file = open(file_path, "rb")
except IOError:
response_first_line = "HTTP/1.1 404 Not Found\r\n"
response_headers = "Server: My Web Static Server\r\n"
response_body = "file is not found"
response = response_first_line + response_headers + "\r\n" + response_body
else:
data = file.read()
file.close()
response_first_line = "HTTP/1.1 200 OK\r\n"
response_headers = "Server: My Web Static Server\r\n"
response_body = data.decode("UTF-8")
response = response_first_line + response_headers + "\r\n" + response_body
# 发送响应报文
client_socket.send(bytes(response, encoding="UTF-8"))
# 关闭socket连接资源
client_socket.close()
if __name__ == "__main__":
'''这是主函数程序运行入口,如果该文件被当做模块导入则不执行'''
# 创建一个服务端的socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 设置服务端socket重复利用端口地址
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# 绑定服务端socket的端口
server_socket.bind(("",8001))
# 设置服务端socket最大同时响应128个客户端请求
server_socket.listen(128)
# 服务端永久等待客户端的请求, 来一个客户端请求则创建一个新的线程响应一个请求
while True:
client_socket, client_address = server_socket.accept()
print('["%s", "%s"]用户已经连接上服务器!' % client_address)
handler = Process(target=handle_request, args=(client_socket,))
handler.start()
client_socket.close()
老男孩python学习自修第二十一天【socket】的更多相关文章
- 老男孩 python学习自修第二十二天【文件上传与下载】
1.使用socket实现文件上传 server.py #!/usr/bin/env python # _*_ coding:UTF-8 _*_ import os import SocketServe ...
- 老男孩python学习自修第二十四天【多进程】
1. 体验多进程的运行速度 #!/usr/bin/env python # _*_ coding:UTF-8 _*_ from multiprocessing import Pool import t ...
- 老男孩python学习自修第二十三天【多线程】
1. 线程的创建与运行 #!/usr/bin/env python # _*_ coding:UTF-8 _*_ from threading import Thread def foo(param1 ...
- 老男孩python学习自修第十九天【异常处理】
1.常见的错误 TypeError 类型错误 NameError 没有该变量 ValueError 不期望的值 AttributeError 没有该属性 UnboundLocalError 没有该局部 ...
- 老男孩python学习自修第十八天【面向对象】
1.类与对象(构造方法与实例化) #!/usr/bin/env python # _*_ coding:UTF-8 _*_ class Province: def __init__(self, nam ...
- 老男孩python学习自修第十七天【装饰器】
装饰器:在某个方法执行前后去执行其他新定义的行为 例如: #!/usr/bin/env python # _*_ coding:UTF-8 _*_ def before_say_hello(): pr ...
- 老男孩python学习自修第十六天【常用模块之sys和os】
例子: sys.argv 命令行参数List,第一个元素是程序本身路径 sys.exit(n) 退出程序,正常退出时exit(0) sys.version 获取Python解释程序的版本信息 sys. ...
- 老男孩python学习自修第十五天【常用模块之time】
例如: #!/usr/bin/env python # _*_ coding:UTF-8 _*_ import time if __name__ == "__main__": pr ...
- 老男孩python学习自修第十四天【序列化和json】
序列化是使用二进制的方式加密列表,字典或集合,反序列化是解密的过程:序列化开启了两个独立进程进行数据交互的通路 使用pickle进行序列化和反序列化 例如: pickle_test.py #!/usr ...
随机推荐
- P2080 增进感情(背包DP)
思路:将好感度x+y作为体积, 幸福度x-y作为作为价值, 然后就是一个经典的背包问题了.emmmmm,还可以特判一下,因为幸福度为0时就是最小了,没有必要看后面的了吧. 其实,我自己做的时候,沙雕的 ...
- P1577 切绳子(二分)
思路:先来分析一下数据范围,是1e4个数据,但是,是double类型,结果不超过0.01那么在绳子最大的情况下,单纯的找正确答案暴力的话就是1e7的时间复杂度,再乘上1e4的数据,这样肯定不行.那么很 ...
- PHP小接
一种是innodb,一种是myisam,两者的主要区别是①myisam不支持事务处理,而innoDB支持事务处理 ②myisam 不支持外键,innoDB支持外键 ③myisam支持全文检索,而inn ...
- Rsync服务实战
目录 1 安装rsync软件 2 配置 /etc/rsyncd.conf 3 创建用户(运行rsync服务的用户身份) 4 创建虚拟用户密码文件(客户端连接时候使用) 5启动 rsync 服务,并加入 ...
- ubantu搭建oj——第一天(6.11)
oj第一份作业: 按照DMOJ的文档将代码搬运到ubantu上 sudo apt install git gcc g++ make python-dev libxml2-dev libxslt1-de ...
- CDB与PDB之间的切换方法
Oracle 12c 开始支持 PLUGGABLE DATABASE,并且提供了一个方法在CDB和PDB之间切换. 1. 使用 show pdbs 可以确认当前有哪些PDB? SQL> show ...
- LeetCode264:Ugly Number II
自己的做法超时了.主要是每次生成一个数据,保存到list中,然后对List重新排序.排序太耗费时间 记录下讨论组里的写法 public int NthUglyNumber(int n) { int[] ...
- Z370主板的黑苹果usb3.0驱动安装
注意每个版本的usb端口代码是不一样的!一般是10.10到10.12 是一个版本,10.13 是一个版本 配合USBInjectAll.kext这个驱动就能顺利驱动你的usb3.0 .如果你是比较新 ...
- 调整代码生成工具Database2Sharp的Winform界面生成,使其易于列表工具栏的使用。
在Winform界面开发的时候,有时候我们客户喜欢把功能放在列表界面的顶部,这样界面和功能整齐放置,也是一种比较美观的方式,基于这种方式的考虑,改造了代码生成工具的Winform界面生成规则,把增删改 ...
- Flask序列化
我们在做后台接口的时候,对于返回值,用的最多的就是json数据格式 flask中,返回json数据格式,我们可以用到flask的jsonify函数. 对于基础序列是可以直接序列化的,但是更多的情况下, ...