[Python] Mini server
Posted mifen2952277346
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Python] Mini server相关的知识,希望对你有一定的参考价值。
一. Web静态服务器
显示固定的页面
# -*- coding: utf-8 -*- # Time : 2019/2/10 18:22 # Author : Mifen # Email : [email protected] # Software: PyCharm import socket def service_client(conn): ‘‘‘接收客户端发送的数据‘‘‘ request = conn.recv(1024) print(request) # 返回客户端请求的数据 response = ‘HTTP/1.1 200 OK\r\n‘ response += ‘\r\n‘ response += ‘你好雇佣兵‘ conn.send(response.encode(‘utf-8‘)) conn.close() def main(): ‘‘‘ 实现主要的功能控制‘‘‘ # 1.创建socket serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 设置当服务器先close 即服务器端4次挥手之后资源能够立即释放,这样就保证了,下次运行程序时 可以立即绑定8080端口 serversocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 2.绑定端口 serversocket.bind((‘‘, 8080)) # 3.监听 serversocket.listen(128) while True: # 4.等待连接 conn, addr = serversocket.accept() # 5.与客户端通信 service_client(conn) if __name__ == ‘__main__‘: main()
显示需要的页面
# -*- coding: utf-8 -*- # Time : 2019/2/10 19:52 # Author : Mifen # Email : [email protected] # Software: PyCharm import socket import re def handle_client(client_socket): "为一个客户端进行服务" recv_data = client_socket.recv(1024).decode(‘utf-8‘, errors="ignore") 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 ===>%s" % get_file_name) # for test # 如果没有指定访问哪个页面。例如index.html # GET / HTTP/1.1 if get_file_name == "/": get_file_name = r‘html/index.html‘ else: get_file_name = ‘html‘ + get_file_name print("file name is ===2>%s" % get_file_name) # for test try: f = open(get_file_name, "rb") except IOError: # 404表示没有这个页面 response_headers = "HTTP/1.1 404 not found\r\n" response_headers += "\r\n" response_body = "404 not found" else: response_headers = "HTTP/1.1 200 OK\r\n" response_headers += "\r\n" response_body = f.read() f.close() finally: # 因为头信息在组织的时候,是按照字符串组织的,不能与以二进制打开文件读取的数据合并,因此分开发送 # 先发送response的头信息 client_socket.send(response_headers.encode(‘utf-8‘)) # 再发送body client_socket.send(response_body) client_socket.close() def main(): "作为程序的主控制入口" server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) server_socket.bind(("127.0.0.1", 8080)) server_socket.listen(128) while True: client_socket, clien_cAddr = server_socket.accept() handle_client(client_socket) # 这里配置服务器 DOCUMENTS_ROOT = "./html" if __name__ == "__main__": main()
多进程、线程实现http服务器
1 # -*- coding: utf-8 -*- 2 # Time : 2019/2/11 19:52 3 # Author : Mifen 4 # Email : [email protected] 5 # Software: PyCharm 6 7 8 import socket 9 import re 10 import threading 11 import multiprocessing 12 13 14 def handle_client(client_socket): 15 "为一个客户端进行服务" 16 recv_data = client_socket.recv(1024).decode(‘utf-8‘, errors="ignore") 17 request_header_lines = recv_data.splitlines() 18 for line in request_header_lines: 19 print(line) 20 21 http_request_line = request_header_lines[0] 22 get_file_name = re.match("[^/]+(/[^ ]*)", http_request_line).group(1) 23 print("file name is ===>%s" % get_file_name) # for test 24 25 # 如果没有指定访问哪个页面。例如index.html 26 # GET / HTTP/1.1 27 if get_file_name == "/": 28 get_file_name = r‘html/index.html‘ 29 else: 30 get_file_name = ‘html‘ + get_file_name 31 32 print("file name is ===2>%s" % get_file_name) # for test 33 34 try: 35 f = open(get_file_name, "rb") 36 except IOError: 37 # 404表示没有这个页面 38 response_headers = "HTTP/1.1 404 not found\r\n" 39 response_headers += "\r\n" 40 response_body = "====sorry ,file not found====" 41 else: 42 response_headers = "HTTP/1.1 200 OK\r\n" 43 response_headers += "\r\n" 44 response_body = f.read() 45 f.close() 46 finally: 47 # 因为头信息在组织的时候,是按照字符串组织的,不能与以二进制打开文件读取的数据合并,因此分开发送 48 # 先发送response的头信息 49 client_socket.send(response_headers.encode(‘utf-8‘)) 50 # 再发送body 51 client_socket.send(response_body) 52 client_socket.close() 53 54 55 def main(): 56 "作为程序的主控制入口" 57 server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 58 server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 59 server_socket.bind(("192.168.43.227", 8080)) 60 server_socket.listen(128) 61 while True: 62 client_socket, clien_cAddr = server_socket.accept() 63 t = threading.Thread(target=handle_client, args=(client_socket,)) 64 t.start() 65 # 如果用多进程实现多任务,因为子进程已经复制了父进程的套接字等资源,所以父进程调用close不会将他们对应的这个链接关闭的 66 # client_socket.close() 67 68 69 # 这里配置服务器 70 DOCUMENTS_ROOT = "./html" 71 72 if __name__ == "__main__": 73 main()
二. Web并发服务器
gevent实现http服务器
# -*- coding: utf-8 -*- # Time : 2019/2/11 20:06 # Author : Mifen # Email : [email protected] # Software: PyCharm import socket import re import gevent from gevent import monkey monkey.patch_all() def handle_client(client_socket): "为一个客户端进行服务" recv_data = client_socket.recv(1024).decode(‘utf-8‘, errors="ignore") 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 ===>%s" % get_file_name) # for test # 如果没有指定访问哪个页面。例如index.html # GET / HTTP/1.1 if get_file_name == "/": get_file_name = r‘html/index.html‘ else: get_file_name = ‘html‘ + get_file_name print("file name is ===2>%s" % get_file_name) #for test try: f = open(get_file_name, "rb") except IOError: # 404表示没有这个页面 response_headers = "HTTP/1.1 404 not found\r\n" response_headers += "\r\n" response_body = "====sorry ,file not found====" else: response_headers = "HTTP/1.1 200 OK\r\n" response_headers += "\r\n" response_body = f.read() f.close() finally: # 因为头信息在组织的时候,是按照字符串组织的,不能与以二进制打开文件读取的数据合并,因此分开发送 # 先发送response的头信息 client_socket.send(response_headers.encode(‘utf-8‘)) # 再发送body client_socket.send(response_body) client_socket.close() def main(): "作为程序的主控制入口" server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) server_socket.bind(("192.168.43.227", 8080)) server_socket.listen(128) while True: client_socket, clien_cAddr = server_socket.accept() gevent.spawn(handle_client,client_socket) #这里配置服务器 DOCUMENTS_ROOT = "./html" if __name__ == "__main__": main()
epoll版的http服务器
# -*- coding: utf-8 -*- # Time : 2019/2/11 22:01 # Author : Mifen # Email : [email protected] # Software: PyCharm import socket import select # 创建套接字 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 设置可以重复使用绑定的信息 s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 绑定本机信息 s.bind(("", 7788)) # 变为被动 s.listen(10) # 创建一个epoll对象 epoll = select.epoll() # epoll只能再Linux下运行 # 测试,用来打印套接字对应的文件描述符 # print(s.fileno()) # print(select.EPOLLIN|select.EPOLLET) # 注册事件到epoll中 # epoll.register(fd[, eventmask]) # 注意,如果fd已经注册过,则会发生异常 # 将创建的套接字添加到epoll的事件监听中 epoll.register(s.fileno(), select.EPOLLIN | select.EPOLLET) connections = addresses = # 循环等待客户端的到来或者对方发送数据 while True: # epoll 进行 fd 扫描的地方 -- 未指定超时时间则为阻塞等待 epoll_list = epoll.poll() # 对事件进行判断 for fd, events in epoll_list: # print fd # print events # 如果是socket创建的套接字被激活 if fd == s.fileno(): new_socket, new_addr = s.accept() print(‘有新的客户端到来%s‘ % str(new_addr)) # 将 conn 和 addr 信息分别保存起来 connections[new_socket.fileno()] = new_socket addresses[new_socket.fileno()] = new_addr # 向 epoll 中注册 新socket 的 可读 事件 epoll.register(new_socket.fileno(), select.EPOLLIN | select.EPOLLET) # 如果是客户端发送数据 elif events == select.EPOLLIN: # 从激活 fd 上接收 recvData = connections[fd].recv(1024).decode("utf-8") if recvData: print(‘recv:%s‘ % recvData) else: # 从 epoll 中移除该 连接 fd epoll.unregister(fd) # server 侧主动关闭该 连接 fd connections[fd].close() print("%s---offline---" % str(addresses[fd])) del connections[fd] del addresses[fd]
以上是关于[Python] Mini server的主要内容,如果未能解决你的问题,请参考以下文章
在Tomcat的安装目录下conf目录下的server.xml文件中增加一个xml代码片段,该代码片段中每个属性的含义与用途
使用实体框架迁移时 SQL Server 连接抛出异常 - 添加代码片段
VITAM POST MORTEM – ANALYZING DEADLOCKED SCHEDULERS MINI DUMP FROM SQL SERVER