Ruby Socket TCPServer发送PNG等二进制文件给客户端显示异常求解
问题原因
你的代码存在4个影响二进制数据传输的问题,HTML对格式容错性高所以能正常展示,二进制格式校验严格就会失效:
- 响应头换行符不符合HTTP标准:HTTP要求所有头部行的结尾必须是
\r\n,你当前拼接头部时每个字段后只加了\n,仅在全部头部拼接完成后加了一次\r\n,不符合协议规范 - 缺少
Content-Length响应头:二进制传输必须明确告知浏览器数据总长度,否则浏览器无法判断接收完成的边界,会将数据识别为不完整内容 - 二进制文件读取方式错误:Ruby的
File.read默认以文本模式读取文件,Windows环境下会自动替换二进制内容中的换行符,直接破坏PNG、可执行文件等二进制数据的结构 - 输出方法会破坏二进制编码:
print方法和to_s调用会自动对内容做字符串编码转换,非文本的二进制内容会在转换过程中损坏
修复后的代码
# Generate and send response def response(client, response = 200, headers, data) client.print "HTTP/1.1 #{response}\r\n" headers.each do |h| # 每个头部行严格使用\r\n结尾 client.print "#{h}\r\n" end # 头部结束标记 client.print "\r\n" # 直接写字节,不做字符串转换 client.write data end # 读取二进制文件要用rb模式,同时添加Content-Length头 img_data = File.open("./very_cool_picture.png", "rb") { |f| f.read } response(client, 200, [ "Content-Type: image/png", "Content-Length: #{img_data.bytesize}" ], img_data)
内容的提问来源于stack exchange,提问作者Matthias Lee
相关产品推荐
相关产品推荐

