
HTTP 协议概念
HTTP 协议,全称是 HyperText Transfer Protocol(超文本传输协议),是一种用于从 Web 服务器传输网页数据到浏览器客户端的网络通信协议。它是整个万维网(WWW)的基础,定义了客户端(比如浏览器)和服务器之间如何请求和响应数据。
一、HTTP 协议的基本特点
特点 | 说明 |
---|---|
应用层协议 | 属于 OSI 七层模型中的应用层,用于 Web 通信 |
基于请求响应 | 客户端发出请求(Request),服务器返回响应(Response) |
无状态协议 | 每次请求之间彼此独立,服务器不会记住之前的交互 |
基于文本 | 报文内容(请求和响应)通常是纯文本,便于人类阅读和调试 |
默认端口 | 默认使用端口号 80 ,HTTPS(加密的 HTTP)使用 443 |
二、HTTP 的基本通信过程
- 客户端发起请求(比如访问
https://example.com
); - DNS 解析域名,获取服务器 IP;
- 客户端向服务器发送 HTTP 请求报文;
- 服务器处理请求,返回 HTTP 响应报文(包括网页 HTML、图片、CSS、JS 等);
- 客户端(如浏览器)解析并展示网页内容。
三、HTTP 请求报文结构
GET /index.html HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0
Accept: text/html
- 请求方法:GET、POST、PUT、DELETE 等;
- 路径:/index.html;
- 协议版本:HTTP/1.1;
- 请求头:告知服务器客户端的能力和偏好;
- 请求体(可选):如 POST 请求时携带的表单数据。
四、HTTP 响应报文结构
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 1234
<html>
<body>Hello, World!</body>
</html>
- 状态行:HTTP 版本 + 状态码(如 200 OK、404 Not Found);
- 响应头:描述响应体的内容类型、长度、缓存控制等;
- 响应体:实际的数据,如网页内容。
五、常见 HTTP 状态码
状态码 | 含义 |
---|---|
200 | 请求成功 |
301 | 永久重定向 |
302 | 临时重定向 |
400 | 请求有误 |
401 | 未授权(需登录) |
403 | 禁止访问 |
404 | 页面未找到 |
500 | 服务器内部错误 |
六、HTTP 的演变(简要)
版本 | 特点 |
---|---|
HTTP/0.9 | 最早期版本,只支持 GET 请求 |
HTTP/1.0 | 增加了请求头和响应头 |
HTTP/1.1 | 引入持久连接、管道化、缓存控制等优化 |
HTTP/2 | 二进制格式、高效传输、多路复用、更快加载速度 |
HTTP/3 | 基于 QUIC 协议,减少延迟,适应现代网络环境 |
客户端和服务器交互的 HTTP 通信流程

什么是 URL
URL(Uniform Resource Locator)统一资源定位符,是互联网上用于标识和定位资源(如网页、图片、视频、API)的地址。
简单来说,URL 就是你在浏览器地址栏输入的地址,例如:
https://www.example.com:443/path/page.html?user=jack&id=123#top
URL 的组成部分
协议://用户名:密码@主机名:端口/路径?查询参数#片段标识
部分 | 示例 | 说明 |
---|---|---|
协议 | https | 指定访问方式,如 http , https , ftp 等 |
用户名:密码 | user:pass@ (可选) | 用于需要认证的 URL,铭文展示,现代浏览器多已禁用此功能 |
主机名 | www.example.com | 域名或 IP 地址 |
端口号 | :443 (可选) | 默认为 80(HTTP)或 443(HTTPS) |
路径 | /path/page.html | 指定访问资源的路径 |
查询参数 | ?user=jack&id=123 | 使用 ? 开始,多个参数用 & 分隔 |
片段标识 | #top | 页面内锚点,不会发送给服务器,仅供浏览器定位 |
查询参数格式详解
key1=value1&key2=value2&key3=value3
- 每个参数由 键值对(key=value) 构成;
- 多个参数之间用
&
分隔; - 中文或特殊字符需要进行 URL 编码(如空格 →
%20
);
Chrome 前端调试工具介绍
打开方式:快捷键:F12
或 Ctrl + Shift + I
(Mac: Cmd + Option + I
)
主要功能面板介绍
面板名 | 主要作用 |
---|---|
Elements | 查看/修改 HTML 和 CSS 结构、调试样式 |
Console | 打印日志、查看报错、执行 JS 代码 |
Sources | 查看页面加载的所有文件,支持设置断点调试 JS |
Network | 查看所有网络请求(接口、图片、CSS 等),可分析加载时间等 |
Application | 管理 Cookie、本地存储、缓存等 |
Performance | 分析网页性能瓶颈、帧率等 |
Lighthouse | 一键生成网页性能报告 |
Device Mode | 切换为手机模拟视图,调试响应式布局 |
常用场景示例
1. 修改网页样式(Elements)
- 选中元素 → 修改 class、style
- 实时预览改动,不影响原网页文件
2. 查看接口数据(Network)
- 切换到 Network 面板
- 刷新页面,查看每个请求的 URL、状态码、响应内容
- 选中某一项 → 查看 Headers、Response、Preview 等
3. 调试 JavaScript(Console & Sources)
- Console 中输入 JS 代码直接运行
- Sources 中设置断点、逐行执行、查看变量
4. 查看本地存储数据(Application)
- 查看或删除 localStorage、sessionStorage、cookie
Network(网络)面板
展示了 HTTP 请求和响应的详细信息,帮助开发者调试网络通信。以下是 HTTP 返回时 Network
面板中常见的主要内容分类:
Headers(请求与响应头)
- General(常规)
- Request URL:请求地址
- Request Method:请求方法(GET、POST、PUT 等)
- Status Code:HTTP 状态码和提示
- Remote Address:远程服务器 IP 和端口
- Referrer Policy:引用策略
- Response Headers(响应头)
Content-Type
:响应内容类型,如application/json
Content-Length
:响应体长度Cache-Control
:缓存策略Set-Cookie
:设置的 Cookie 信息Server
:服务器类型(如 nginx)
- Request Headers(请求头)
Host
:目标服务器域名User-Agent
:浏览器信息Accept
:可接受的响应类型Authorization
:认证信息(如 Bearer Token)Cookie
:发送的 Cookie
Preview(预览)
- 渲染后的响应内容预览,适用于 JSON、HTML、图像等类型

Response(原始响应内容)
- 响应体的原始数据(如 JSON 字符串、HTML 文本)

Initiator(触发器)
- 展示是哪段代码或资源触发了这个请求(通常是 JS)

Timing(时间)
- 展示详细的请求时间线,包括:
- Stalled(阻塞时间)
- DNS Lookup
- Initial Connection
- SSL
- Request Sent
- Waiting (TTFB: 首字节时间)
- Content Download

Cookies
- 显示请求中发送的 Cookie 和响应中设置的 Cookie

HTTP 请求报文
GET 方式的请求报文
例如:
GET /search?keyword=chatgpt&page=1 HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9
Connection: keep-alive
Referer: https://www.example.com/
请求行
GET /search?keyword=chatgpt&page=1 HTTP/1.1
请求行字段 | 含义 |
---|---|
GET | 请求方法 |
/search?... | 路径 + 查询参数 |
HTTP/1.1 | 协议版本 |
请求头
Host: www.example.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7
Accept: text/html,application/xhtml+xml,application/xml;q=0.9
Connection: keep-alive
Referer: https://www.example.com/
这些是浏览器自动添加的,告诉服务器:
- 谁发的请求(User-Agent)
- 请求了什么类型的数据(Accept)
- 连接是否复用(Connection)
- 来源页是哪个(Referer)
请求体
GET 方法 没有请求体。所有参数都放在 URL 里。
POST 方式的请求报文
例如:
POST /login HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)
Content-Type: application/x-www-form-urlencoded
Content-Length: 29
Connection: keep-alive
username=admin&password=123456
请求行
POST /login HTTP/1.1
字段 | 含义 |
---|---|
POST | 请求方法 |
/login | 请求路径 |
HTTP/1.1 | 协议版本 |
请求头
Host: www.example.com
User-Agent: Mozilla/5.0 ...
Content-Type: application/x-www-form-urlencoded
Content-Length: 29
Connection: keep-alive
说明了:
- 要发送的数据是表单格式(Content-Type)
- 内容长度为 29 字节(Content-Length)
请求体
username=admin&password=123456
表单数据真实内容,这才是服务器要接收和处理的用户提交信息。
GET/POST 总结对比
项目 | GET | POST |
---|---|---|
请求体 | ❌ 没有 | ✅ 有 |
参数位置 | URL 后的 ?query | 请求体中 |
数据可见性 | 暴露在地址栏 | 不显示在地址栏 |
安全性 | 相对较低(可被缓存/记录) | 相对更高(适合敏感数据) |
长度限制 | 有限制(URL 长度) | 理论无限(服务器配置限制) |
常见用途 | 查询、获取数据 | 提交数据,如表单、上传 |
HTTP 响应报文

举个例子:完整响应报文示例(200 OK)
--- 状态行(Status Line) ---
HTTP/1.1 200 OK
--- 响应头(Response Headers) ---
Date: Sun, 08 Jun 2025 11:30:00 GMT
Content-Type: application/json
Content-Length: 37
Server: nginx/1.18.0
Set-Cookie: sessionid=abc123; Path=/; HttpOnly
--- 空行 ---
--- 响应体(Response Body) ---
{
"status": "success",
"data": "hello"
}
状态行(Status Line)
格式如下:
<HTTP版本> <状态码> <状态短语>
响应头(Headers)
用于说明响应的服务器信息、内容类型、缓存策略等。
常见响应头如下:
响应头 | 说明 |
---|---|
Content-Type | 响应体内容的类型,如 text/html 、application/json |
Content-Length | 响应体的字节长度 |
Server | 服务器软件信息,如 nginx/1.18.0 |
Date | 响应发送的时间 |
Set-Cookie | 服务端设置 Cookie |
Cache-Control | 是否缓存、缓存时长等 |
Content-Encoding | 内容压缩方式,如 gzip 、br |
Access-Control-Allow-Origin | CORS 跨域控制头 |
Location | 重定向地址(3xx 响应时出现) |
ETag | 响应资源的唯一标识,用于缓存比较 |
空行
请求头与响应体之间用一个空行(\r\n
)隔开,表示 响应头结束,响应体开始。
响应体(Body)
- 客户端真正接收到的内容,比如 HTML 页面、JSON 数据、图片、文件等。
- 不同的
Content-Type
会导致响应体格式不同。
示例:
Content-Type: application/json
→ 响应体是 JSON:
{"code":200,"message":"登录成功"}
Content-Type: text/html
→ 响应体是网页 HTML:
<html><body><h1>Hello</h1></body></html>
搭建 Python 自带的 web 静态服务器
静态 Web 服务器是什么?
静态 Web 服务器专门用来存储并直接“原样”返回静态资源(如 HTML 文件、图片、CSS、JS 等)的服务器。它不处理业务逻辑、不操作数据库,仅仅负责把文件送出去。
什么是“静态资源”?
静态资源 = 内容固定、服务器不需要计算就能返回的文件:
类型 | 示例 |
---|---|
HTML 页面 | index.html 、about.html |
图片 | .jpg 、.png 、.svg |
样式表 | .css |
JavaScript 脚本 | .js |
文档文件 | .pdf 、.txt |
静态 Web 服务器的作用
当你访问网页(如 https://example.com/index.html
)时,静态服务器会:
- 根据 URL 找到对应的文件
- 加载它
- 原样发送给浏览器
不做任何修改、不接触数据库、不执行脚本。
常见静态 Web 服务器软件
软件 | 简介 |
---|---|
Nginx | 高性能 Web 服务器,静态文件处理效率极高 |
Apache HTTP Server | 功能丰富,也可以做静态资源服务 |
Node.js + Express + express.static | 用于前端开发时快速启动本地静态服务 |
Python 内置 HTTP Server | 用于调试,非常轻量 |
Vite / Webpack Dev Server | 前端开发中的临时本地静态服务器 |
GitHub Pages / Vercel / Netlify | 提供免费静态网站托管服务(CI/CD 支持) |
Python 快速启动静态服务器
假设你有一个包含 index.html
(内容为 hello web) 的文件夹 site/
:
cd site/
python3 -m http.server 8000
访问:http://localhost:8000/ → 就能访问你的静态网站

原始 TCP Socket 手写最简版的静态 Web 服务器
实现思路:
- 用
socket
模块创建 TCP 服务端; - 监听端口,等待浏览器发来 HTTP request请求;
- 读取并解析 HTTP request请求;
- 根据请求的路径查找对应的文件并返回;
- 按照 HTTP 协议格式拼接 response 返回响应内容。
完整代码:
server_socket.py
import socket
import os
HOST = '127.0.0.1'
PORT = 8080
STATIC_DIR = 'static' # 静态资源目录
def get_content_type(file_path):
if file_path.endswith('.html'):
return 'text/html'
elif file_path.endswith('.css'):
return 'text/css'
elif file_path.endswith('.js'):
return 'application/javascript'
elif file_path.endswith('.png'):
return 'image/png'
elif file_path.endswith('.jpg') or file_path.endswith('.jpeg'):
return 'image/jpeg'
elif file_path.endswith('.ico'):
return 'image/x-icon'
else:
return 'text/plain'
def handle_request(client_socket):
try:
request = client_socket.recv(1024).decode('utf-8')
if not request:
print("没有收到请求,关闭连接")
return # 提前返回,但 socket 仍会在 finally 中被关闭。
print('📥 收到请求:')
print(request)
# 提取请求路径
path_line = request.splitlines()[0]
method, path, _ = path_line.split()
if path == '/':
path = '/index.html'
file_path = os.path.join(STATIC_DIR, path.lstrip('/'))
# 构建响应
if os.path.isfile(file_path):
with open(file_path, 'rb') as f:
body = f.read()
content_type = get_content_type(file_path)
response = (
'HTTP/1.1 200 OK\r\n'
f'Content-Type: {content_type}; charset=utf-8\r\n'
f'Content-Length: {len(body)}\r\n'
'\r\n'
).encode('utf-8') + body
else:
body = b"<h1>404 Not Found</h1>"
response = (
'HTTP/1.1 404 Not Found\r\n'
'Content-Type: text/html; charset=utf-8\r\n'
f'Content-Length: {len(body)}\r\n'
'\r\n'
).encode('utf-8') + body
client_socket.sendall(response)
except Exception as e:
print(f"处理请求时发生错误: {e}")
finally:
client_socket.close() # 确保客户端套接字在最后始终关闭
def start_server():
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server:
server.bind((HOST, PORT))
server.listen(5)
print(f"🌐 Server is running at http://{HOST}:{PORT}/")
while True:
client_socket, addr = server.accept()
handle_request(client_socket)
if __name__ == '__main__':
start_server()
使用说明
- 创建
static/
文件夹; - 放入一个简单的
index.html
(例如):
<!DOCTYPE html>
<html><body><h1>Hello Socket!</h1></body></html>
- 运行服务器
python3 server_socket.py
- 打开浏览器访问:
http://127.0.0.1:8080/
request:

reponse headers:

response body

全代码详解
import socket
import os
# 服务监听地址和端口
HOST = '127.0.0.1'
PORT = 8080
# 存放网站静态资源的文件夹
STATIC_DIR = 'static'
函数:get_content_type(file_path)
这个函数是根据文件后缀判断 MIME 类型,用于构造响应头中的 Content-Type
def get_content_type(file_path):
if file_path.endswith('.html'):
return 'text/html'
elif file_path.endswith('.css'):
return 'text/css'
elif file_path.endswith('.js'):
return 'application/javascript'
elif file_path.endswith('.png'):
return 'image/png'
elif file_path.endswith('.jpg') or file_path.endswith('.jpeg'):
return 'image/jpeg'
elif file_path.endswith('.ico'):
return 'image/x-icon'
else:
return 'text/plain' # 默认类型
函数:handle_request(client_socket)
这个函数用来处理客户端的一次 HTTP 请求。
def handle_request(client_socket):
try:
request = client_socket.recv(1024).decode('utf-8')
if not request:
print("没有收到请求,关闭连接")
return # 提前返回,但 socket 仍会在 finally 中被关闭。
print('📥 收到请求:')
print(request)
示例请求报文(GET):
GET /index.html HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 ...
Accept: text/html,...
解析请求行
path_line = request.splitlines()[0] # 只取第一行(请求行)
method, path, _ = path_line.split() # 拆分 GET /index.html HTTP/1.1
if path == '/':
path = '/index.html' # 默认首页
文件路径转换
file_path = os.path.join(STATIC_DIR, path.lstrip('/')) # 构造完整文件路径
构建响应报文(重点!)
HTTP 响应由三部分构成:
响应行(Status Line)
响应头(Response Headers)
空行(\r\n)
响应体(Body)
如果文件存在(200 OK):
if os.path.isfile(file_path):
with open(file_path, 'rb') as f:
body = f.read() # 读取二进制文件内容作为响应体
content_type = get_content_type(file_path)
# 构造响应行 + 响应头
response = (
'HTTP/1.1 200 OK\r\n' # 状态行
f'Content-Type: {content_type}; charset=utf-8\r\n' # 响应头
f'Content-Length: {len(body)}\r\n' # 响应头
'\r\n' # 空行,后面开始是 body
).encode('utf-8') + body # 拼接:响应头 + 响应体(二进制)
response
是拼接好的完整响应报文!
如果文件不存在(404 Not Found):
else:
body = b"<h1>404 Not Found</h1>" # 返回的内容
response = (
'HTTP/1.1 404 Not Found\r\n' # 状态行
'Content-Type: text/html; charset=utf-8\r\n' # 响应头
f'Content-Length: {len(body)}\r\n' # 响应头
'\r\n' # 空行
).encode('utf-8') + body # 拼接响应头+体
发送响应并关闭连接
client_socket.sendall(response)
except Exception as e:
print(f"处理请求时发生错误: {e}")
finally:
client_socket.close() # 确保客户端套接字在最后始终关闭
函数:start_server()
这是整个 Web 服务的入口。
def start_server():
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server:
server.bind((HOST, PORT)) # 绑定地址端口
server.listen(5) # 开始监听,最多 5 个等待连接
print(f"🌐 Server is running at http://{HOST}:{PORT}/")
while True:
client_socket, addr = server.accept() # 接收一个连接
handle_request(client_socket) # 交给处理函数
总结:响应报文构造位置
部分 | 构造位置 |
---|---|
响应行(如 HTTP/1.1 200 OK ) | response = (...) 开头处的第一行 |
响应头(如 Content-Type , Content-Length ) | 在 .encode('utf-8') 前用字符串拼接 |
响应体(HTML / 图片 / CSS) | 用 + body 拼接进去,必须是二进制 |
完整响应报文 | response = encode(响应行 + 响应头 + 空行) + body |
发送 | client_socket.sendall(response) |
使用线程实现多任务
import socket
import os
import threading
HOST = '127.0.0.1'
PORT = 8080
STATIC_DIR = 'static' # 静态资源目录
def get_content_type(file_path):
if file_path.endswith('.html'):
return 'text/html'
elif file_path.endswith('.css'):
return 'text/css'
elif file_path.endswith('.js'):
return 'application/javascript'
elif file_path.endswith('.png'):
return 'image/png'
elif file_path.endswith('.jpg') or file_path.endswith('.jpeg'):
return 'image/jpeg'
elif file_path.endswith('.ico'):
return 'image/x-icon'
else:
return 'text/plain'
def handle_request(client_socket):
try:
request = client_socket.recv(1024).decode('utf-8')
if not request:
print("没有收到请求,关闭连接")
return # 提前返回,但 socket 仍会在 finally 中被关闭。
print('📥 收到请求:')
print(request)
# 提取请求路径
path_line = request.splitlines()[0]
method, path, _ = path_line.split()
if path == '/':
path = '/index.html'
file_path = os.path.join(STATIC_DIR, path.lstrip('/'))
# 构建响应
if os.path.isfile(file_path):
with open(file_path, 'rb') as f:
body = f.read()
content_type = get_content_type(file_path)
response = (
'HTTP/1.1 200 OK\r\n'
f'Content-Type: {content_type}; charset=utf-8\r\n'
f'Content-Length: {len(body)}\r\n'
'\r\n'
).encode('utf-8') + body
else:
body = b"<h1>404 Not Found</h1>"
response = (
'HTTP/1.1 404 Not Found\r\n'
'Content-Type: text/html; charset=utf-8\r\n'
f'Content-Length: {len(body)}\r\n'
'\r\n'
).encode('utf-8') + body
client_socket.sendall(response)
except Exception as e:
print(f"处理请求时发生错误: {e}")
finally:
client_socket.close() # 确保客户端套接字在最后始终关闭
def start_server():
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server:
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind((HOST, PORT))
server.listen(5)
print(f"🌐 Server is running at http://{HOST}:{PORT}/")
while True:
client_socket, addr = server.accept()
print(f"👤 连接来自: {addr}")
# 创建一个新线程来处理请求
thread = threading.Thread(target=handle_request, args=(client_socket,))
thread.start() # 启动线程
if __name__ == '__main__':
start_server()
代码优化说明
- 引入多线程支持:
- 在
start_server
函数中,当有新连接接受时,创建一个新的threading.Thread
实例来处理该连接。 - 通过
args=(client_socket,)
将当前的client_socket
传递给handle_request
函数。
- 在
- 线程启动:
- 使用
thread.start()
方法来启动线程,这样每个客户端的请求都会在自己的线程中处理。
- 使用
面向对象写法
为什么改为面向对象
- 结构更清晰:把功能封装进类中,每个类职责明确。
- 更容易扩展:比如后续想支持 POST 方法、日志模块、安全认证、模板引擎等。
- 更方便测试与复用:每个方法可以单独测试,不需要跑整个服务器。
- 面向对象的封装和继承更适合大型项目开发。
import socket
import os
import threading
class SimpleHTTPServer:
def __init__(self, host='127.0.0.1', port=8080, static_dir='static'):
self.host = host
self.port = port
self.static_dir = static_dir
def get_content_type(self, file_path):
if file_path.endswith('.html'):
return 'text/html'
elif file_path.endswith('.css'):
return 'text/css'
elif file_path.endswith('.js'):
return 'application/javascript'
elif file_path.endswith('.png'):
return 'image/png'
elif file_path.endswith('.jpg') or file_path.endswith('.jpeg'):
return 'image/jpeg'
elif file_path.endswith('.ico'):
return 'image/x-icon'
else:
return 'text/plain'
def handle_request(self, client_socket):
try:
request = client_socket.recv(1024).decode('utf-8')
if not request:
print("没有收到请求,关闭连接")
return
print('📥 收到请求:')
print(request)
path_line = request.splitlines()[0]
method, path, _ = path_line.split()
if path == '/':
path = '/index.html'
file_path = os.path.join(self.static_dir, path.lstrip('/'))
if os.path.isfile(file_path):
with open(file_path, 'rb') as f:
body = f.read()
content_type = self.get_content_type(file_path)
response = (
'HTTP/1.1 200 OK\r\n'
f'Content-Type: {content_type}; charset=utf-8\r\n'
f'Content-Length: {len(body)}\r\n'
'\r\n'
).encode('utf-8') + body
else:
body = b"<h1>404 Not Found</h1>"
response = (
'HTTP/1.1 404 Not Found\r\n'
'Content-Type: text/html; charset=utf-8\r\n'
f'Content-Length: {len(body)}\r\n'
'\r\n'
).encode('utf-8') + body
client_socket.sendall(response)
except Exception as e:
print(f"处理请求时发生错误: {e}")
finally:
client_socket.close()
def start(self):
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server:
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind((self.host, self.port))
server.listen(5)
print(f"🌐 Server is running at http://{self.host}:{self.port}/")
while True:
client_socket, addr = server.accept()
print(f"👤 连接来自: {addr}")
thread = threading.Thread(target=self.handle_request, args=(client_socket,))
thread.start()
if __name__ == '__main__':
server = SimpleHTTPServer()
server.start()
以访问命令行参数使用 sys.argv
列表来获取命令行输入
import socket
import os
import threading
import sys
class SimpleHTTPServer:
def __init__(self, host='127.0.0.1', port=8080, static_dir='static'):
self.host = host
self.port = port
self.static_dir = static_dir
def get_content_type(self, file_path):
if file_path.endswith('.html'):
return 'text/html'
elif file_path.endswith('.css'):
return 'text/css'
elif file_path.endswith('.js'):
return 'application/javascript'
elif file_path.endswith('.png'):
return 'image/png'
elif file_path.endswith('.jpg') or file_path.endswith('.jpeg'):
return 'image/jpeg'
elif file_path.endswith('.ico'):
return 'image/x-icon'
else:
return 'text/plain'
def handle_request(self, client_socket):
try:
request = client_socket.recv(1024).decode('utf-8')
if not request:
print("没有收到请求,关闭连接")
return
print('📥 收到请求:')
print(request)
path_line = request.splitlines()[0]
method, path, _ = path_line.split()
if path == '/':
path = '/index.html'
file_path = os.path.join(self.static_dir, path.lstrip('/'))
if os.path.isfile(file_path):
with open(file_path, 'rb') as f:
body = f.read()
content_type = self.get_content_type(file_path)
response = (
'HTTP/1.1 200 OK\r\n'
f'Content-Type: {content_type}; charset=utf-8\r\n'
f'Content-Length: {len(body)}\r\n'
'\r\n'
).encode('utf-8') + body
else:
body = b"<h1>404 Not Found</h1>"
response = (
'HTTP/1.1 404 Not Found\r\n'
'Content-Type: text/html; charset=utf-8\r\n'
f'Content-Length: {len(body)}\r\n'
'\r\n'
).encode('utf-8') + body
client_socket.sendall(response)
except Exception as e:
print(f"处理请求时发生错误: {e}")
finally:
client_socket.close()
def start(self):
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server:
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind((self.host, self.port))
server.listen(5)
print(f"🌐 Server is running at http://{self.host}:{self.port}/")
while True:
client_socket, addr = server.accept()
print(f"👤 连接来自: {addr}")
thread = threading.Thread(target=self.handle_request, args=(client_socket,))
thread.start()
if __name__ == '__main__':
# 使用 sys.argv 获取命令行参数
host = sys.argv[1] if len(sys.argv) > 1 else '127.0.0.1'
port = int(sys.argv[2]) if len(sys.argv) > 2 else 8080
static_dir = sys.argv[3] if len(sys.argv) > 3 else 'static'
# 创建服务器实例,使用命令行参数
server = SimpleHTTPServer(host=host, port=port, static_dir=static_dir)
server.start()
执行格式:
python server_socket.py 127.0.0.1 8080 static

发布者:LJH,转发请注明出处:https://www.ljh.cool/42427.html