解決http協議的面向物件開發web伺服器響應圖片亂碼問題
阿新 • • 發佈:2018-12-14
今天練習的時候發現當瀏覽器請求是圖片的時候,伺服器返回的是亂碼。
原始碼如下:
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()