代码:
1 import socket 2 import re 3 import multiprocessing 4 import threading 5 import gevent 6 from gevent import monkey 7 8 monkey.patch_all() 9 10 11 def client_msg(new_client): 12 # 接收客户端请求 13 recv_data = new_client.recv(1024).decode("utf-8") 14 # 把读出的数据分行 15 recv_data_lines = recv_data.splitlines() 16 # 正则匹配GET后面的请求的页面 17 # [^/]表示非“/”字符 +表示至少1个或多个,[^ ]只要不是空格,*表示0个或多个 18 ret = re.match(r"[^/]+(/[^ ]*)",recv_data_lines[0]) 19 20 # ret = re.search(r"/[^ ]*",recv_data_lines[0]) # 查找第一次“/”后面非空格的字符串 21 file_name = ret.group(1) 22 print(file_name) 23 # 打开文件 24 try: 25 f = open("./html" + file_name,"rb") 26 except: 27 # 创建返回数据 HEADER 28 response = "HTTP/1.1 404 NOT FOUND\r\n" 29 response += "\r\n" 30 response += "-----NOT FOUND----" 31 # 发送数据到客户端 32 new_client.send(response.encode("utf-8")) 33 else: 34 # 读出数据 35 html_content = f.read() 36 37 # 创建返回数据 HEADER 38 response = "HTTP/1.1 200 ok\r\n" 39 response += "\r\n" 40 41 # 发送数据到客户端 42 new_client.send(response.encode("utf-8")) 43 new_client.send(html_content) 44 45 # 关闭套接字 46 new_client.close() 47 48 49 def main(): 50 # 创建套接字 51 tcp_server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM) 52 # 设置当服务器先调用close() 即服务器4次回收之后资源能够立即释放,这样就保证了下次运行程序时,可以立即使用 53 # SO_REUSEADDR重复使用地址 54 tcp_server_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) 55 # 绑定端口 56 tcp_server_socket.bind(("",7890)) 57 # 设置监听状态 58 tcp_server_socket.listen(128) 59 # 新建为客户端服务的套接字 60 while True: 61 new_client,client_addr = tcp_server_socket.accept() 62 # 调用服务方法 63 # client_msg(new_client) 64 # 多进程方法 为多个客户同时服务 65 # p = multiprocessing.Process(target=client_msg,args=(new_client,)) 66 # p.start() 67 # new_client.close() 68 # 多线程方法 注意:多线程时主线程不能关闭 69 # t = threading.Thread(target=client_msg,args=(new_client,)) 70 # t.start() 71 # 协程方法 72 gevent.spawn(client_msg, new_client) 73 74 # 关闭套接字 75 tcp_server_socket.close()