Python 基础 HTTP 客户端与服务端的请求收发实现

Dylan
Dylan
发布时间:2026-10-12 | 4人浏览过
原创

本文详细讲解如何使用 Python 标准库实现 HTTP 客户端的请求发送与服务端的响应接收。通过适配现代 Python 3 的内置模块,演示如何组装带自定义头的 POST 报文,重写处理器拦截路由并解析请求体,同时阐明 Content-Length 在防阻塞中的关键作用。

Python HTTP 客户端与服务端请求处理核心逻辑

在实际项目开发中,手动构建底层 HTTP 交互能够避开重型框架开销,精准控制握手细节。本文将分步演示如何编写轻量级的客户端发送脚本与服务端接收程序。需要说明的是,原始资料基于 Python 2 环境,考虑到现代系统兼容性,以下代码已全面升级至 Python 3 标准库(http.client / urllib.request 与 http.server)。

环境准备与原理概述

本示例完全依赖 Python 内置模块,无需安装任何第三方依赖。客户端负责将参数序列化、填充 Header 并建立 TCP 连接;服务端通过继承基类重写路由方法,从 rfile 流中按字节提取 POST 报文,并最终通过 wfile 返回 HTML 响应。

第1步:编写客户端发送请求

目的:向目标地址发起携带自定义请求头的 POST 交互。

入口:任意支持终端运行的 Python 3 环境。参数:目标主机、端口、路径、表单数据及 Headers。

# 导入标准库模块
import urllib.request
import urllib.parse

# 1. 序列化待发送的参数字典
data = {'param': '6'}
params = urllib.parse.urlencode(data).encode('utf-8')

# 2. 配置请求头(注意:Length 需动态匹配实际数据大小)
headers = {
    "Content-Type": "application/x-www-form-urlencoded",
    "Connection": "Keep-Alive",
    "Content-Length": str(len(params))
}

# 3. 构建 Request 对象并发起 POST 请求
req = urllib.request.Request(
    url='http://localhost:8765/',
    data=params,
    headers=headers,
    method='POST'
)

try:
    # 使用上下文管理器自动管理连接关闭
    with urllib.request.urlopen(req) as response:
        print(response.read().decode('utf-8'))
        if response.status == 200:
            print("发布成功!^_^!")
        else:
            print("发布失败")
except Exception as e:
    print(f"网络或连接异常: {e}")

第2步:搭建服务端接收与处理请求

目的:监听指定端口,区分 GET 与 POST 请求并安全读取请求体。

入口:新建 server.py。参数:绑定地址(默认监听全部接口)与端口 8765。

from http.server import HTTPServer, BaseHTTPRequestHandler

class RequestHandler(BaseHTTPRequestHandler):
    def _send_response_headers(self):
        # 记录请求路径与头部,便于调试
        print(self.path)
        print(self.headers)
        
        self.send_response(200)
        self.send_header('Content-type', 'text/html; charset=utf-8')
        self.end_headers()

    def do_GET(self):
        self._send_response_headers()
        body = """<!DOCTYPE HTML>
<html lang="zh-CN"><head><meta charset="UTF-8"><title>GET Response</title></head>
<body><p>this is get!</p></body></html>"""
        self.wfile.write(body.encode('utf-8'))

    def do_POST(self):
        self._send_response_headers()
        
        # 获取 Content-Length 防止未知长度的阻塞读取
        length_header = self.headers.get('Content-Length')
        if not length_header:
            self.wfile.write(b"<p>Error: Missing Content-Length</p>")
            return

        nbytes = int(length_header)
        raw_data = self.rfile.read(nbytes)

        body = f"""<!DOCTYPE HTML>
<html lang="zh-CN"><head><meta charset="UTF-8"><title>POST Response</title></head>
<body><p>this is post! Data received:</p><pre>{raw_data.decode('utf-8', errors='ignore')}</pre></body></html>"""
        self.wfile.write(body.encode('utf-8'))

# 初始化服务器实例
addr = ('', 8765)
server = HTTPServer(addr, RequestHandler)
print("服务端已启动,正在监听 localhost:8765 ...")
try:
    server.serve_forever()
except KeyboardInterrupt:
    print("\n收到中断信号,安全关闭服务...")
    server.server_close()

第3步:验证运行状态

目的:确认双向通信链路通畅及数据流转正确。

操作顺序:优先在后台运行服务端脚本,保持终端处于监听状态;随后切换窗口执行客户端脚本。若控制台依次打印请求路径、响应正文及“发布成功”,即代表连接建立、报文解析与断开流程均符合预期。

关键注意事项与排错指南

  • 强制声明 Content-Length:原文明确指出,若客户端未传递有效的 Content-Length,服务端执行 rfile.read() 时将无限期阻塞等待 EOF。Python 3 环境下务必通过 str(len(params)) 动态补全该字段。
  • 字符编码转换:HTTP 传输底层为字节流,服务端读取到 raw_data 后需配合 .decode('utf-8') 还原文本;写入响应体时需统一进行 .encode('utf-8') 处理,避免产生乱码。
  • 网络绑定范围:addr = ('', 8765) 中的空字符串代表绑定 0.0.0.0(所有可用网卡)。本地测试无妨,若部署于公网服务器,建议显式指定内网 IP 以收敛暴露面。

以上就是 Python 实现 HTTP 客户端发送与服务端接收请求教程的详细内容,更多关于 Python 网络编程基础及本地服务搭建的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表