HyperText Transfer Protocol:超文本传输协议,由蒂姆·伯纳斯-李于1991年设计。指超越限制的文本或者超链接,比如:图片、音乐、视频、超链接等都属于超文本。原本目的是传输网页数据的,现在允许传输任意类型的数据。 http协议基于 TCP 传输协议的,发送数据之前需要先建立连接。它规定了浏览器和 Web 服务器通信数据的格式,也就是说浏览器和web服务器通信需要使用http协议。
GET / HTTP/1.1\r\n Host: www.itcast.cn\r\n Connection: keep-alive\r\n Upgrade-Insecure-Requests: 1\r\n User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36\r\n Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\r\n Accept-Encoding: gzip, deflate\r\n Accept-Language: zh-CN,zh;q=0.9\r\n Cookie: pgv_pvi=1246921728; \r\n \r\n (请求头信息后面还有一个单独的’\r\n’不能省略)
post请求报文
1 2 3 4 5 6 7 8 9 10
---- 请求行 ---- POST /xmweb?host=mail.itcast.cn&_t=1542884567319 HTTP/1.1 # POST请求方式 请求资源路径 HTTP协议版本 ---- 请求头 ---- Host: mail.itcast.cn # 服务器的主机地址和端口号,默认是80 Connection: keep-alive # 和服务端保持长连接 Content-Type: application/x-www-form-urlencoded # 服务端响应回客户端的数据类型 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36 # 客户端的名称 ---- 空行 ---- ---- 请求体 ---- username=hello&pass=hello # 请求参数
post请求原始报文(每项数据之间使用:**\r\n**)
1 2 3 4 5 6 7
POST /xmweb?host=mail.itcast.cn&_t=1542884567319 HTTP/1.1\r\n Host: mail.itcast.cn\r\n Connection: keep-alive\r\n Content-Type: application/x-www-form-urlencoded\r\n User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36\r\n \r\n(请求头信息后面还有一个单独的’\r\n’不能省略) username=hello&pass=hello
# handler client request defhandler_client_request(new_socket): # receive data,4kb recv_client_data = new_socket.recv(4096) # handle receive data length is zero iflen(recv_client_data) == 0: new_socket.close() return # decode bin data recv_client_data = recv_client_data.decode('utf-8') print(recv_client_data) # calculae request path request_list = recv_client_data.split(" ", maxsplit=2) request_path = request_list[1] # handler / request,return default index.html if request_path == "/": request_path = "index.html" # handler 404 # os.path.exists("static/"+request_path) try: # open user request resource file withopen("static" + request_path, "rb") as file: # read file data file_data = file.read() except Exception as e: # handler resource file not exist # response line response_line = "HTTP/1.1 404 Not Found\r\n" # response head response_head = "Server: nginx\r\n" withopen("static/error.html", "rb") as file: # read file data file_data = file.read() # reponse content response_body = file_data # response response_data = (response_line + response_head + "\r\n").encode("utf-8") + response_body # send data new_socket.send(response_data) else: # response line response_line = "HTTP/1.1 200 OK\r\n" # response head response_head = "Server: nginx\r\n" # reponse content response_body = file_data # response response_data = (response_line + response_head + "\r\n").encode("utf-8") + response_body # send data new_socket.send(response_data) finally: # close socket new_socket.close()
defmain(): # tcp server socket tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # port reuse,t system release port right now tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True) # bing port,default 8000 tcp_server_socket.bind(('', 8000)) # set listen num tcp_server_socket.listen(128) whileTrue: # wait accept client request new_socket, ip_port = tcp_server_socket.accept() # multi thread handler many user request sub_thread = threading.Thread(target=handler_client_request,args=(new_socket,)) # set daemon thread sub_thread.setDaemon(True) # start sub thread sub_thread.start()
import os import socket import sys import threading
# web server classHttpWebServer(object): # init server method def__init__(self, port): # tcp server socket tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # port reuse,t system release port right now tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True) # bing port,default 8000 tcp_server_socket.bind(('', port)) # set listen num tcp_server_socket.listen(128) # set object attribute self.tcp_server_socket = tcp_server_socket
# start server method defstart(self): whileTrue: # wait accept client request new_socket, ip_port = self.tcp_server_socket.accept() # multi thread handler many user request sub_thread = threading.Thread(target=self.handler_client_request, args=(new_socket,)) # set daemon thread sub_thread.setDaemon(True) # start sub thread sub_thread.start()
# handler client request @staticmethod defhandler_client_request(new_socket): # receive data,4kb recv_client_data = new_socket.recv(4096) # handle receive data length is zero iflen(recv_client_data) == 0: new_socket.close() return # decode bin data recv_client_data = recv_client_data.decode('utf-8') print(recv_client_data) # calculae request path request_list = recv_client_data.split(" ", maxsplit=2) request_path = request_list[1] # handler / request,return default index.html if request_path == "/": request_path = "index.html" # handler 404 # os.path.exists("static/"+request_path) try: # open user request resource file withopen("static" + request_path, "rb") as file: # read file data file_data = file.read() except Exception as e: # handler resource file not exist # response line response_line = "HTTP/1.1 404 Not Found\r\n" # response head response_head = "Server: nginx\r\n" withopen("static/error.html", "rb") as file: # read file data file_data = file.read() # reponse content response_body = file_data # response response_data = (response_line + response_head + "\r\n").encode("utf-8") + response_body # send data new_socket.send(response_data) else: # response line response_line = "HTTP/1.1 200 OK\r\n" # response head response_head = "Server: nginx\r\n" # reponse content response_body = file_data # response response_data = (response_line + response_head + "\r\n").encode("utf-8") + response_body # send data new_socket.send(response_data) finally: # close socket new_socket.close()
defmain(): print(sys.argv) # common line args length is equals 2? python3 + file_name + port iflen(sys.argv) != 2: print("execute common: python3 xxx.py 8000") return # judge args is number ifnot sys.argv[1].isdigit(): print("execute common: python3 xxx.py 8000") return # get port args port = int(sys.argv[1]) # create web server web_server = HttpWebServer(port) # start web server web_server.start()