zoukankan      html  css  js  c++  java
  • Python网络编程之 select(2)实现一个最简单的webserver

              上次介绍了Python 的select模块实现非阻塞socket编程。于是就用select写了一个最简单的web Server,能够实现最基本的HTML文件访问和Python脚本的访问,当然有很多bug,只是想通过这个这个对socket编程以及HTTP协议有一些了解。

        

      1 __author__ = 'gongxingfa'
      2 
      3 import socket
      4 import os
      5 import traceback
      6 import select
      7 from os.path import splitext
      8 
      9 HOST = 'localhost'
     10 PORT = 8000
     11 BUFSIZ = 1024
     12 ADDR = (HOST, PORT)
     13 
     14 # context
     15 socketMap = {}
     16 requestMap = {}
     17 r, w, e = [], [], []
     18 
     19 # setting server socket
     20 serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     21 serverSocket.bind(ADDR)
     22 serverSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
     23 serverSocket.listen(100)
     24 
     25 
     26 class Request(object):
     27     def __init__(self, message):
     28         headers = {}
     29         try:
     30             message = message.strip().splitlines()
     31             self.start = message[0].strip().split(' ')
     32             for i in range(1, len(message)):
     33                 line = message[i]
     34                 if line.strip() != '':
     35                     index = line.index(':')
     36                     key = line[0: index]
     37                     value = line[index + 1:]
     38                     headers[key] = value
     39         except IndexError, e:
     40             pass
     41         self.headers = headers
     42 
     43     def method(self):
     44         return self.start[0]
     45 
     46     def url(self):
     47         return self.start[1]
     48 
     49     def version(self):
     50         return self.start[2]
     51 
     52 
     53 def handler(req, reqClnt):
     54     try:
     55         path = '.' + req.url()
     56         ext = splitext(path)
     57         if ext[1] == '':
     58             f = os.popen('python ' + path + '.py')
     59             reqClnt.send('\n'.join(f.readlines()))
     60             f.close()
     61         else:
     62             f = open('.' + req.url())
     63             reqClnt.send('\n'.join(f.readlines()))
     64             f.close()
     65     except IOError, e:
     66         reqClnt.send(str(e))
     67 
     68 
     69 socketFileno = serverSocket.fileno()
     70 socketMap[socketFileno] = serverSocket
     71 print 'start socket ', socketFileno, '*' * 50
     72 
     73 try:
     74     while True:
     75         r, w, e = [], [], []
     76         for fd in socketMap:
     77             r.append(fd)
     78             w.append(fd)
     79             e.append(fd)
     80         r, w, e = select.select(r, w, e, 1)
     81         for fd in r:
     82             isocket = socketMap[fd]
     83             if fd == socketFileno:
     84                 print 'accepting...........'
     85                 clientSock, clientAddr = isocket.accept()
     86                 print 'connection from ', clientAddr
     87                 clientFileno = clientSock.fileno()
     88                 r.append(clientFileno)
     89                 w.append(clientFileno)
     90                 e.append(clientFileno)
     91                 socketMap[clientFileno] = clientSock
     92             else:
     93                 print 'reading............'
     94                 requestMap[fd] = Request(isocket.recv(BUFSIZ))
     95 
     96         for fd in w:
     97             try:
     98                 req = requestMap[fd]
     99             except KeyError, e:
    100                 pass
    101             else:
    102                 print 'writing.............'
    103                 osocket = socketMap[fd]
    104                 handler(req, osocket)
    105                 del requestMap[fd]
    106 
    107         for fd in e:
    108             esocket = socketMap[fd]
    109             print 'socket close ', fd
    110             esocket.close()
    111             del socketMap[fd]
    112         print 'no data coming'
    113 
    114 except Exception, e:
    115     print traceback.print_exc()
    116     serverSocket.close()
  • 相关阅读:
    Redis单点登录
    MySQL有哪些存储引擎,各自的优缺点,应用场景
    MySQL慢查询优化、索引优化、以及表等优化总结
    Redis缓存和MySQL数据一致性方案详解
    Jenkies+github实现代码自动构建
    Python基础-day14-单元测试注册小例子
    Python基础-day13-unitest框架(Suite、runner)及生成报告,附带最新的HTMLTestRunnerNew.py文件
    Python基础-day11-继承和动态设置属性
    Python基础-day10-类的创建和调用
    Python基础-day03 字符串
  • 原文地址:https://www.cnblogs.com/ArtsCrafts/p/Python_select2.html
Copyright © 2011-2022 走看看