• http协议、web服务器、并发服务器(上)


    1. HTTP格式

    每个HTTP请求和响应都遵循相同的格式,一个HTTP包含Header和Body两部分,其中Body是可选的。HTTP协议是一种文本协议,所以,它的格式也非常简单。

    1.1 HTTP GET请求的格式:

    GET /path HTTP/1.1
    Header1: Value1
    Header2: Value2
    Header3: Value3
    

    1.2 HTTP POST请求的格式:

    POST /path HTTP/1.1
    Header1: Value1
    Header2: Value2
    Header3: Value3
    
    body data goes here...
    

    当遇到连续两个 时,Header部分结束,后面的数据全部是Body。

    1.3 HTTP响应的格式:

    HTTP/1.1 200 OK
    Header1: Value1
    Header2: Value2
    Header3: Value3
    
    body data goes here...
    

    HTTP响应如果包含body,也是通过 来分隔的。

    请再次注意,Body的数据类型由Content-Type头来确定,如果是网页,Body就是文本,如果是图片,Body就是图片的二进制数据。

    当存在Content-Encoding时,Body数据是被压缩的,最常见的压缩方式是gzip,所以,看到Content-Encoding: gzip时,需要将Body数据先解压缩,才能得到真正的数据。压缩的目的在于减少Body的大小,加快网络传输。

    2. Web静态服务器-显示固定的页面

    import socket
    
    
    def handle_client(new_client):
            """处理客户端请求"""
    
            recv_data = new_client.recv(1024)
    
            print(recv_data)
        
            # 组装响应的内容
            response_headers = "HTTP/1.1 200 OK
    "
            response_headers += "
    "
            response_body = "6666"
        
            response = response_headers + response_body
            new_client.send(response.encode("utf-8"))
    
            new_client.close()
    
    
    def main():
        
            # 创建套接字
            tcp_socket_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        
            # 绑定本地消息
            tcp_socket_server.bind(("", 8090))
    
            # 套接字由主动变被动
            tcp_socket_server.listen(128)
        
            while True:
        
                    # 接收新的请求
                    new_client, client_addr = tcp_socket_server.accept()
    
                    handle_client(new_client)
    
            # 关闭套接字
            tcp_socket_server.close()
    
    
    if __name__ == "__main__":
    
            main()
    

    如上的代码仅仅只是向浏览器发送了简单的文本内容:6666

    在浏览器中访问:

    3. Web静态服务器-显示需要的页面

    import socket
    import re
    
    
    def handle_client(new_client):
    	"""处理客户端请求"""
    
    	recv_data = new_client.recv(1024).decode("utf-8")
    	
    	# GET / HTTP/1.1
    	request_header_lines = recv_data.splitlines()
    	for line in request_header_lines:
    		print(line)
    	http_request_line = request_header_lines[0];
    	get_file_name = re.match("[^/]+(/[^ ]*)", http_request_line).group(1)
    	print("file name is -> " + get_file_name)	
    
    	# print(recv_data)
    	if get_file_name == "/":
    		get_file_name = "/index.html"	
    
    	root_path = "./html"
    	get_file_name = root_path + get_file_name;
    	try:
    		f = open(get_file_name, "rb")
    	except:
    		response_headers = "HTTP/1.1 404 NOT FOUND
    "
    		response_headers += "
    "
    		response_body = b"page not found"
    	else:	
    	
    		# 组装响应的内容
    		response_headers = "HTTP/1.1 200 OK
    "
    		response_headers += "
    "
    		response_body = f.read()
    		f.close()
    	
    	new_client.send(response_headers.encode("utf-8"))
    	new_client.send(response_body)
    
    	new_client.close()
    
    
    def main():
    	
    	# 创建套接字
    	tcp_socket_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    	tcp_socket_server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)	
    	
    	# 绑定本地消息
    	tcp_socket_server.bind(("", 8090))
    
    	# 套接字由主动变被动
    	tcp_socket_server.listen(128)
    	
    	while True:
    		
    		# 接收新的请求
    		new_client, client_addr = tcp_socket_server.accept()
    
    		handle_client(new_client)
    
    	# 关闭套接字
    	tcp_socket_server.close()
    
    
    if __name__ == "__main__":
    
    	main()
    

    在浏览器中访问:

    4. Web静态服务器-多进程版

    import socket
    import re
    import multiprocessing
    
    
    def handle_client(new_client):
    	"""处理客户端请求"""
    
    	recv_data = new_client.recv(1024).decode("utf-8")
    	
    	# GET / HTTP/1.1
    	request_header_lines = recv_data.splitlines()
    	for line in request_header_lines:
    		print(line)
    	http_request_line = request_header_lines[0];
    	get_file_name = re.match("[^/]+(/[^ ]*)", http_request_line).group(1)
    	print("file name is -> " + get_file_name)	
    
    	# print(recv_data)
    	if get_file_name == "/":
    		get_file_name = "/index.html"	
    
    	root_path = "./html"
    	get_file_name = root_path + get_file_name;
    	try:
    		f = open(get_file_name, "rb")
    	except:
    		response_headers = "HTTP/1.1 404 NOT FOUND
    "
    		response_headers += "
    "
    		response_body = b"page not found"
    	else:	
    	
    		# 组装响应的内容
    		response_headers = "HTTP/1.1 200 OK
    "
    		response_headers += "
    "
    		response_body = f.read()
    		f.close()
    	
    	new_client.send(response_headers.encode("utf-8"))
    	new_client.send(response_body)
    
    	new_client.close()
    
    
    def main():
    	
    	# 创建套接字
    	tcp_socket_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    	tcp_socket_server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)	
    	
    	# 绑定本地消息
    	tcp_socket_server.bind(("", 8090))
    
    	# 套接字由主动变被动
    	tcp_socket_server.listen(128)
    	
    	while True:
    		
    		# 接收新的请求
    		new_client, client_addr = tcp_socket_server.accept()
    		
    		p = multiprocessing.Process(target=handle_client, args=(new_client,))
    		p.start()
    		
    		new_client.close()
    		
    	# 关闭套接字
    	tcp_socket_server.close()
    
    
    if __name__ == "__main__":
    
    	main()
    
    

    5. Web静态服务器-多线程版

    import socket
    import re
    import threading
    
    
    def handle_client(new_client):
    	"""处理客户端请求"""
    
    	recv_data = new_client.recv(1024).decode("utf-8")
    	
    	# GET / HTTP/1.1
    	request_header_lines = recv_data.splitlines()
    	for line in request_header_lines:
    		print(line)
    	http_request_line = request_header_lines[0];
    	get_file_name = re.match("[^/]+(/[^ ]*)", http_request_line).group(1)
    	print("file name is -> " + get_file_name)	
    
    	# print(recv_data)
    	if get_file_name == "/":
    		get_file_name = "/index.html"	
    
    	root_path = "./html"
    	get_file_name = root_path + get_file_name;
    	try:
    		f = open(get_file_name, "rb")
    	except:
    		response_headers = "HTTP/1.1 404 NOT FOUND
    "
    		response_headers += "
    "
    		response_body = b"page not found"
    	else:	
    	
    		# 组装响应的内容
    		response_headers = "HTTP/1.1 200 OK
    "
    		response_headers += "
    "
    		response_body = f.read()
    		f.close()
    	
    	new_client.send(response_headers.encode("utf-8"))
    	new_client.send(response_body)
    
    	new_client.close()
    
    
    def main():
    	
    	# 创建套接字
    	tcp_socket_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    	tcp_socket_server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)	
    	
    	# 绑定本地消息
    	tcp_socket_server.bind(("", 8090))
    
    	# 套接字由主动变被动
    	tcp_socket_server.listen(128)
    	
    	while True:
    		
    		# 接收新的请求
    		new_client, client_addr = tcp_socket_server.accept()
    		
    		t = threading.Thread(target=handle_client, args=(new_client,))
    		t.start()
    		
    	# 关闭套接字
    	tcp_socket_server.close()
    
    
    if __name__ == "__main__":
    
    	main()
    
    

    6. Web静态服务器-gevent版

    import socket
    import re
    import gevent
    from gevent import monkey
    
    
    monkey.patch_all()
    
    
    def handle_client(new_client):
    	"""处理客户端请求"""
    
    	recv_data = new_client.recv(1024).decode("utf-8")
    	
    	# GET / HTTP/1.1
    	request_header_lines = recv_data.splitlines()
    	for line in request_header_lines:
    		print(line)
    	http_request_line = request_header_lines[0];
    	get_file_name = re.match("[^/]+(/[^ ]*)", http_request_line).group(1)
    	print("file name is -> " + get_file_name)	
    
    	# print(recv_data)
    	if get_file_name == "/":
    		get_file_name = "/index.html"	
    
    	root_path = "./html"
    	get_file_name = root_path + get_file_name;
    	try:
    		f = open(get_file_name, "rb")
    	except:
    		response_headers = "HTTP/1.1 404 NOT FOUND
    "
    		response_headers += "
    "
    		response_body = b"page not found"
    	else:	
    	
    		# 组装响应的内容
    		response_headers = "HTTP/1.1 200 OK
    "
    		response_headers += "
    "
    		response_body = f.read()
    		f.close()
    	
    	new_client.send(response_headers.encode("utf-8"))
    	new_client.send(response_body)
    
    	new_client.close()
    
    
    def main():
    	
    	# 创建套接字
    	tcp_socket_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    	tcp_socket_server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)	
    	
    	# 绑定本地消息
    	tcp_socket_server.bind(("", 8090))
    
    	# 套接字由主动变被动
    	tcp_socket_server.listen(128)
    	
    	while True:
    		
    		# 接收新的请求
    		new_client, client_addr = tcp_socket_server.accept()
    		
    		g = gevent.spawn(handle_client, new_client)
    		g.join()
    		
    	# 关闭套接字
    	tcp_socket_server.close()
    
    
    if __name__ == "__main__":
    
    	main()
    
  • 相关阅读:
    在LinuxMint 17 MATE中安装NVIDIA显卡驱动
    如何在VeryCD中下载资源
    创建多个Dialog时,namespace冲突问题的解决 -- 基于QT 5.2
    Qt 5.2中编译加载MySQL数据库驱动问题的总结
    Python入门 -- 001
    Qt 入门 ---- 布局管理
    Qt 入门 ---- 如何在程序窗口显示图片?
    Redis 教程笔记
    Python pip 报错
    Python手动安装 package
  • 原文地址:https://www.cnblogs.com/zhangfengxian/p/10182138.html
Copyright © 2020-2023  润新知