1. 程式人生 > >解決http協議的面向物件開發web伺服器響應圖片亂碼問題

解決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()

結果如下:

後來在網上查資料發現,請求的是圖片時,響應行“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()