You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

HTTP请求Chunked分块传输原理、发送方式及Python实现咨询

HTTP分块(Chunked)传输机制解析

核心原理澄清

分块传输不是基于Keep-Alive的多个HTTP请求,它是同一个HTTP请求内的连续数据流。当请求头设置Transfer-Encoding: chunked后,整个请求/响应体被拆分成多个"块"依次发送:

  • 每个块的结构为「十六进制的块长度 + \r\n + 块内容 + \r\n」
  • 最后用「0\r\n\r\n」标记整个传输结束

你设想的发送方式是错误的——拆分的块必须属于同一个HTTP请求,不能拆成多个独立HTTP请求发送。每个HTTP请求有自己的请求头和边界,分块是在单个请求的体内部做的拆分。

正确格式示例

你看到的标准示例是合规的,格式拆解如下:

4\r\n        # 十六进制4,对应4字节数据
Wiki\r\n     # 实际数据("Wiki"刚好4字节)
6\r\n        # 十六进制6,对应6字节数据
pedia \r\n   # 实际数据("pedia "是6字节)
E\r\n        # 十六进制E=14,对应14字节数据
in \r\n\r\nchunks.\r\n  # 实际数据,长度刚好14字节
0\r\n\r\n    # 结束标记,0表示无后续块,最后两个\r\n是结束分隔

Python实现示例

服务端(接收分块请求)

用原生socket实现,手动解析分块数据:

import socket

def handle_chunked_data(conn):
    # 读取请求头,直到空行
    headers = b""
    while b"\r\n\r\n" not in headers:
        headers += conn.recv(1024)
    
    # 检查是否启用分块传输
    if b"Transfer-Encoding: chunked" not in headers:
        conn.send(b"HTTP/1.1 400 Bad Request\r\n\r\nNeed chunked encoding")
        return
    
    # 解析分块数据
    body = b""
    while True:
        # 读取块长度行
        chunk_len_line = b""
        while b"\r\n" not in chunk_len_line:
            chunk_len_line += conn.recv(1)
        chunk_len = int(chunk_len_line.strip(), 16)
        
        if chunk_len == 0:
            # 读取结束的空行
            conn.recv(2)
            break
        
        # 读取块内容和后续的\r\n
        chunk_data = conn.recv(chunk_len)
        conn.recv(2)
        body += chunk_data
    
    # 返回响应
    response = f"HTTP/1.1 200 OK\r\nContent-Length: {len(body)}\r\n\r\nReceived data: {body.decode()}"
    conn.send(response.encode())
    conn.close()

# 启动服务
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(("localhost", 8080))
server_socket.listen(1)
print("Server listening on port 8080...")

while True:
    conn, addr = server_socket.accept()
    handle_chunked_data(conn)

客户端(发送分块请求)

模拟发送分块数据:

import socket

def send_chunked_request():
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect(("localhost", 8080))
    
    # 构造请求头
    request_headers = (
        "POST /test HTTP/1.1\r\n"
        "Host: localhost:8080\r\n"
        "Transfer-Encoding: chunked\r\n"
        "\r\n"
    )
    sock.send(request_headers.encode())
    
    # 依次发送各个块
    sock.send(b"4\r\nWiki\r\n")
    sock.send(b"6\r\npedia \r\n")
    sock.send(b"E\r\nin \r\n\r\nchunks.\r\n")
    # 发送结束块
    sock.send(b"0\r\n\r\n")
    
    # 接收并打印响应
    response = sock.recv(4096)
    print(response.decode())
    sock.close()

if __name__ == "__main__":
    send_chunked_request()

内容的提问来源于stack exchange,提问作者brian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 21:35:18