平时我们开发web大部分情况下直接使用框架现拉的一个底层,今天我们来徒手撸一个简单的web服务器程序,通过这个简单的示例让你对框架是如何做到有更深的理解。
python自带静态web服务器
其实python给我们自带了一个静态web服务器,我们使用命令行随便进入到一个有静态文件的目录中,运行如下命令:
1 2
   | Tony-iMac:diandian_blog tony$ python3 -m http.server 8001 Serving HTTP on :: port 8001 (http://[::]:8001/) ...
   | 
-m选项说明:
-m表示运行包里面的模块,执行这个命令的时候,需要进入你自己指定静态文件的目录,然后通过浏览器就能访问对应的 html文件了,这样一个静态的web服务器就搭建好了。
此时访问浏览器
![]()
- 静态Web服务器是为发出请求的浏览器提供静态文档的程序,
 - 搭建Python自带的Web服务器使用python3 –m http.server 端口号 这个命令即可,端口号不指定默认是8000
 
开发自己的静态Web服务器
在上一篇TCP网络应用程序开发流程回顾中,我们已经回顾了网络应用的开发流程,知道了HTTP协议本质上就是基于TCP,只不过http是一个通信一次即断开的TCP,相较于之前的交互型TCP应用是应该是更简单的。
我们这里只需要写一套服务端socket即可,浏览器是一个天生的客户端,代码中也包含了详细的注释,故也不在其他地方做解释。
响应固定页面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
   | 
 
 
 
 
 
 
  import socket
 
  socket_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  socket_server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
  socket_server.bind(('localhost', 9999))
  socket_server.listen(3) print("服务端开始运行了……")
  while True:          client_socket, ip_port = socket_server.accept()     print(ip_port, '连接上线了')          recv_data = client_socket.recv(4096)          recv_data_length = len(recv_data)          if recv_data_length == 0:         client_socket.close()         print(ip_port, '断开了与服务器的链接')          response_line = 'HTTP/1.1 200 OK\r\n'          response_header = 'Server: PWS1.0\r\n'          empty_line = '\r\n'          response_body = '<!DOCTYPE HTML><html><head><meta charset="UTF-8"><title>我是标题</title></head><body><h1>我是内容</h1></body></html>'          response_data = (response_line+response_header+empty_line+response_body).encode('utf8')          client_socket.send(response_data)          client_socket.close()
 
  | 
注:以上响应体response_body我们使用的html代码,如果内容过多可直接使用with open打开html文件访问,此处简单演示,故不作文件打开操作
响应指定页面(进阶)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
   | 
 
 
 
 
 
 
  import socket
 
  socket_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  socket_server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
  socket_server.bind(('localhost', 9999))
  socket_server.listen(3) print("服务端开始运行了……")
  while True:          client_socket, ip_port = socket_server.accept()     print(ip_port, '连接上线了')          recv_data = client_socket.recv(4096)          recv_data_length = len(recv_data)          if recv_data_length == 0:         client_socket.close()         print(ip_port, '断开了与服务器的链接')          response_line = 'HTTP/1.1 200 OK\r\n'          response_header = 'Server: PWS1.0\r\n'          empty_line = '\r\n'          format_data = recv_data.decode('utf8').split(' ', maxsplit=2)          if format_data[1] == '/':                  response_body = '<!DOCTYPE HTML><html><head><meta charset="UTF-8"><title>首页</title></head><body><h1>我是首页</h1></body></html>'     else:         response_body = '<!DOCTYPE HTML><html><head><meta charset="UTF-8"><title>错误页</title></head><body><h1>该页面出错了</h1></body></html>'          response_data = (response_line+response_header+empty_line+response_body).encode('utf8')          client_socket.send(response_data)          client_socket.close()
 
  | 
多任务版静态web服务器(再进阶)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
   | 
 
 
 
 
 
 
  import socket import threading
 
  def client_socket_handle(client_socket):          recv_data = client_socket.recv(4096)          recv_data_length = len(recv_data)          if recv_data_length == 0:         client_socket.close()          response_line = 'HTTP/1.1 200 OK\r\n'          response_header = 'Server: PWS1.0\r\n'          empty_line = '\r\n'          format_data = recv_data.decode('utf8').split(' ', maxsplit=2)     print(format_data)          if format_data[1] == '/':                  response_body = '<!DOCTYPE HTML>' \                         '<html>' \                         '<head>' \                         '<meta charset="UTF-8">' \                         '<title>首页</title>' \                         '</head>' \                         '<body><h1>我是首页</h1></body>' \                         '</html>'     else:         response_body = '<!DOCTYPE HTML><html>' \                         '<head>' \                         '<meta charset="UTF-8">' \                         '<title>错误页</title>' \                         '</head>' \                         '<body><h1>该页面出错了</h1></body>' \                         '</html>'          response_data = (response_line + response_header + empty_line + response_body).encode('utf8')          client_socket.send(response_data)          client_socket.close()
 
  def main():          socket_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)          socket_server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)          socket_server.bind(('localhost', 9999))          socket_server.listen(3)     print("服务端开始运行了……")          while True:                  client_socket, ip_port = socket_server.accept()         print(ip_port, '连接上线了')                  main_thread = threading.Thread(target=client_socket_handle, args=(client_socket,))                  main_thread.setDaemon(True)                  main_thread.start()
  if __name__ == '__main__':     main()
 
  | 
面向对象版静态web服务器(继续进阶)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
   | 
 
 
 
 
 
 
  import socket import threading
  class HttpServer(object):     """面向对象静态web服务器"""     def __init__(self):                  self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)                  self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)                  self.server_socket.bind(('', 9999))                  self.server_socket.listen(128)         print("服务端开始运行了……")
      @staticmethod     def client_socket_handle(client_socket):                  recv_data = client_socket.recv(4096)                  recv_data_length = len(recv_data)                  if recv_data_length == 0:             client_socket.close()                  response_line = 'HTTP/1.1 200 OK\r\n'                  response_header = 'Server: PWS1.0\r\n'                  empty_line = '\r\n'                  format_data = recv_data.decode('utf8').split(' ', maxsplit=2)         print(format_data)                  if format_data[1] == '/':                          response_body = '<!DOCTYPE HTML>' \                             '<html>' \                             '<head>' \                             '<meta charset="UTF-8">' \                             '<title>首页</title>' \                             '</head>' \                             '<body><h1>我是首页</h1></body>' \                             '</html>'         else:             response_body = '<!DOCTYPE HTML><html>' \                             '<head>' \                             '<meta charset="UTF-8">' \                             '<title>错误页</title>' \                             '</head>' \                             '<body><h1>该页面出错了</h1></body>' \                             '</html>'                  response_data = (response_line + response_header + empty_line + response_body).encode('utf8')                  client_socket.send(response_data)                  client_socket.close()
      def main(self):                  while True:                          client_socket, ip_port = self.server_socket.accept()             print(ip_port, '连接上线了')                          main_thread = threading.Thread(target=self.client_socket_handle, args=(client_socket,))                          main_thread.setDaemon(True)                          main_thread.start()
 
  if __name__ == '__main__':     http_server = HttpServer()     http_server.main()
 
  | 
命令行启动静态web服务器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
   | 
 
 
 
 
 
 
  import socket import sys import threading
 
  class HttpServer(object):     """面向对象静态web服务器"""     def __init__(self, port=9998):                  self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)                  self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)                  self.server_socket.bind(('', port))                  self.server_socket.listen(128)         print("服务端开始运行了……")
      @staticmethod     def client_socket_handle(client_socket):                  recv_data = client_socket.recv(4096)                  recv_data_length = len(recv_data)                  if recv_data_length == 0:             client_socket.close()                  response_line = 'HTTP/1.1 200 OK\r\n'                  response_header = 'Server: PWS1.0\r\n'                  empty_line = '\r\n'                  format_data = recv_data.decode('utf8').split(' ', maxsplit=2)         print(format_data)                  if format_data[1] == '/':                          response_body = '<!DOCTYPE HTML>' \                             '<html>' \                             '<head>' \                             '<meta charset="UTF-8">' \                             '<title>首页</title>' \                             '</head>' \                             '<body><h1>我是首页</h1></body>' \                             '</html>'         else:             response_body = '<!DOCTYPE HTML><html>' \                             '<head>' \                             '<meta charset="UTF-8">' \                             '<title>错误页</title>' \                             '</head>' \                             '<body><h1>该页面出错了</h1></body>' \                             '</html>'                  response_data = (response_line + response_header + empty_line + response_body).encode('utf8')                  client_socket.send(response_data)                  client_socket.close()
      def start(self):                  while True:                          client_socket, ip_port = self.server_socket.accept()             print(ip_port, '连接上线了')                          main_thread = threading.Thread(target=self.client_socket_handle, args=(client_socket,))                          main_thread.setDaemon(True)                          main_thread.start()
 
  def main():          shell_argvs = sys.argv          if len(shell_argvs) != 2:         print("启动命令如下: python3 xxx.py 9090")         return False          if not shell_argvs[1].isdigit():         print("端口必须为数字")         return False     http_server = HttpServer(int(shell_argvs[1]))     http_server.start()
 
  if __name__ == '__main__':     main()
 
 
  | 
到这里我们其实已经明白了Django怎么使用一行命令就把服务给启动起来了,看到我们这里的简化版本,原来也就这么简单。