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()

 

posted on 2013-04-25 13:08  Arts&Crafts  阅读(339)  评论(0编辑  收藏  举报

导航