Python中如何解码从requests发送至Server Socket的数据?
如何解码requests发送到服务器套接字的数据?
首先得指出你当前遇到的核心问题:你看到的二进制数据是TLS握手报文,不是明文HTTP请求——这是因为你的客户端用了https://localhost:80发起请求,但你的服务器只是个普通的TCP套接字,完全没处理TLS加密层,所以接收到的是客户端启动TLS连接的初始握手数据,根本不是你预期的带参数的HTTP请求。
下面给你几个可行的解决方向:
方向1:改用明文HTTP协议
这是最快速的解决方式,只需要修改客户端的请求地址,把https改成http:
import requests payload = {'key1': 'value1', 'key2': 'value2'} # 去掉s,用HTTP协议 r = requests.get('http://localhost:80', params=payload) print(r)
这时你的服务器收到的data就是明文的HTTP GET请求,直接用data.decode('utf-8')就能解码成可读的字符串,比如会看到类似GET /?key1=value1&key2=value2 HTTP/1.1\r\nHost: localhost\r\n...的内容。
方向2:让服务器支持HTTPS(处理TLS)
如果一定要用HTTPS,你需要给你的TCP套接字加上TLS处理层,Python的ssl模块可以帮你做到这一点。注意HTTPS默认用443端口,建议把服务器端口改成443:
服务器端修改示例
import socket import ssl # 创建基础TCP套接字 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) port = 443 s.bind(('', port)) s.listen(5) # 创建SSL上下文,加载证书(可以用自签名证书) # 生成自签名证书的命令:openssl req -x509 -newkey rsa:4096 -keyout server.key -out server.crt -days 365 -nodes context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) context.load_cert_chain(certfile="server.crt", keyfile="server.key") while True: c, addr = s.accept() # 把普通套接字包装成SSL套接字 ssl_conn = context.wrap_socket(c, server_side=True) data = ssl_conn.recv(5048) print('Got connection from', addr) # 现在可以解码HTTP请求了 print(data.decode('utf-8')) ssl_conn.send('Thank you for connecting'.encode()) ssl_conn.close()
客户端修改示例
因为用的是自签名证书,requests会默认拒绝,所以需要加上verify=False跳过证书验证:
import requests payload = {'key1': 'value1', 'key2': 'value2'} r = requests.get('https://localhost:443', params=payload, verify=False) print(r)
方向3:解析原始TLS报文(仅用于学习分析)
如果你只是想搞懂收到的二进制数据是什么,可以手动解析TLS握手报文的结构:
- 开头的
\x16是TLS的Handshake类型标识; \x03\x01表示TLS版本为TLS 1.0;- 后面的
\x02\x00是握手报文的长度,\x01\x00\x01\xfc等是握手的具体内容(比如客户端随机数、会话ID等)。
不过手动解析很繁琐,更高效的方式是用Wireshark抓包,直接查看TLS握手的详细字段。
内容的提问来源于stack exchange,提问作者ddd_newus
相关产品推荐
相关产品推荐

