解决http协议的面向对象开发web服务器响应图片乱码问题

今天练习的时候发现当浏览器请求是图片的时候,服务器返回的是乱码。

源代码如下:

import socket

import re

import gevent
from gevent import monkey
monkey.patch_all()


class WebServer(object):
    # 初始化,创建tcp服务器
    def __init__(self):
        # tcp服务器
        tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        tcp_server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        tcp_server.bind(('', 8080))
        tcp_server.listen(128)
        self.tcp_server = tcp_server

    # 开始接收请求
    def startaccept(self):
        while True:
            client, addr = self.tcp_server.accept()
            gevent.spawn(self.handle_request,client)

    @staticmethod
    def handle_request(client):
        # 接收浏览器发的报文
        request_data = client.recv(1024).decode('utf-8')

        # 使用正则匹配出报文中的地址
        match = re.match('.+(/.*?) ', request_data)

        # 判断地址是否存在
        if match:
            # 报文存在,返回报文地址
            print('报文地址为:', match.group(1))

        # 根据地址返回数据
        else:
            # 报文地址不存在
            # 关闭
            client.close()
            return

        # 进行到这步,则报文地址存在
        request_path=match.group(1)
        # 响应行
        response_line='http/1.1 200 ok\r\n'
        # 响应头
        response_head='content-type:/text/html;charset=utf-8\r\n'
        
        #
        if request_path == '/index.html':
            with open('./2.jpg', 'rb') as f:
                content = f.read()
                # response_body=content.decode('utf-8')

        response_data=(response_line + response_head+ '\r\n').encode('utf-8') + content
        client.send(response_data)
        client.close()

def main():
    web=WebServer()
    web.startaccept()


if __name__ == '__main__':
    main()

结果如下:

解决http协议的面向对象开发web服务器响应图片乱码问题

 

后来在网上查资料发现,请求的是图片时,响应行“Content-Type”应为“image/jpeg”,或者发送响应数据的时候不加响应头。

现代码如下:


import socket

import re

import gevent
from gevent import monkey
monkey.patch_all()


class WebServer(object):
    # 初始化,创建tcp服务器
    def __init__(self):
        # tcp服务器
        tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        tcp_server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        tcp_server.bind(('', 8080))
        tcp_server.listen(128)
        self.tcp_server = tcp_server

    # 开始接收请求
    def startaccept(self):
        while True:
            client, addr = self.tcp_server.accept()
            gevent.spawn(self.handle_request,client)

    @staticmethod
    def handle_request(client):
        # 接收浏览器发的报文
        request_data = client.recv(1024).decode('utf-8')

        # 使用正则匹配出报文中的地址
        match = re.match('.+(/.*?) ', request_data)

        # 判断地址是否存在
        if match:
            # 报文存在,返回报文地址
            print('报文地址为:', match.group(1))

        # 根据地址返回数据
        else:
            # 报文地址不存在
            # 关闭
            client.close()
            return

        # 进行到这步,则报文地址存在
        request_path=match.group(1)
        # 响应行
        response_line='http/1.1 200 ok\r\n'
        # 响应头
        response_head='content-type:image/jpeg;charset=utf-8\r\n'
        
        #
        if request_path == '/index.html':
            with open('./2.jpg', 'rb') as f:
                content = f.read()
                # response_body=content.decode('utf-8')

        response_data=(response_line + response_head+ '\r\n').encode('utf-8') + content
        client.send(response_data)
        client.close()

def main():
    web=WebServer()
    web.startaccept()


if __name__ == '__main__':
    main()