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) 编辑 收藏 举报