Python socket实现HTTP服务器 浏览器无法显示HTML问题求解
问题根因定位
- 最核心诱因:HTTP响应结构完全不符合协议规范
浏览器对TCP传输流的解析逻辑有固定规则:必须识别到连续的两个\r\n(即空行)作为响应头区域的结束标记,空行之后的所有传输内容才会被判定为HTML响应体。当前代码仅发送了一行状态行HTTP/1.1 200 OK\r\n,既缺失了Content-Type、Content-Length这类必要的响应头字段,也没有加头区结束的空行,浏览器无法判断传输边界,自然不会触发渲染逻辑,最终表现为空白页。 - 认知误区:
send返回1或3并非故障send方法的返回值代表单次调用实际成功写入socket缓冲区的字节数:ASCII字符(英文字母、常用符号)UTF-8编码后占1字节,返回值为1;中文等多字节字符UTF-8编码后占3字节,返回值为3,这是完全正常的运行表现。逐字符循环调用send的写法仅会产生大量不必要的系统调用开销,并非页面空白的原因。 - 代码隐性错误
原代码中host变量未定义,正常执行serverSocket.bind((host, TCPPort))时会直接抛出NameError,需要替换为''(等价于监听所有网卡地址)才能正常建立连接。另外Windows绝对路径写法'\HTML.html'指向磁盘根目录的文件,当脚本启动工作目录与预期不符时会直接触发文件读取失败,建议替换为相对路径'./HTML.html'匹配脚本同目录下的文件。
修正后可直接运行的代码
from socket import * serverSocket = socket(AF_INET, SOCK_STREAM) TCPPort = 8000 BufferSize = 1024 # 绑定所有可用网卡地址 serverSocket.bind(('', TCPPort)) serverSocket.listen(1) while True: print('Ready to serve...') (connectionSocket, addr) = serverSocket.accept() print('connectionSocket is:', connectionSocket) try: message = connectionSocket.recv(BufferSize) print('message is:', message) # 读取同目录下的HTML文件 with open('./HTML.html', 'r', encoding='UTF-8') as f: outputdata = f.read() # 编码响应体并计算实际字节长度 response_body = outputdata.encode('UTF-8') body_length = len(response_body) # 构造符合规范的完整HTTP响应头 response_header = ( 'HTTP/1.1 200 OK\r\n' f'Content-Type: text/html; charset=utf-8\r\n' f'Content-Length: {body_length}\r\n' 'Connection: close\r\n' '\r\n' # 响应头与响应体的分隔标记 ).encode('UTF-8') # 一次性发送全部响应内容 connectionSocket.sendall(response_header + response_body) connectionSocket.close() except IOError: # 构造符合规范的404响应 error_body = '<html><head></head><body><h1>404 Not Found</h1></body></html>'.encode('UTF-8') error_header = ( 'HTTP/1.1 404 Not Found\r\n' f'Content-Type: text/html; charset=utf-8\r\n' f'Content-Length: {len(error_body)}\r\n' 'Connection: close\r\n' '\r\n' ).encode('UTF-8') connectionSocket.sendall(error_header + error_body) connectionSocket.close() serverSocket.close()
内容的提问来源于stack exchange,提问作者WonSeok JIN
相关产品推荐
相关产品推荐

