您的位置:首页 > 理论基础 > 计算机网络

Python网络编程之 select(2)实现一个最简单的webserver

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

    

__author__ = 'gongxingfa'

import socket
import os
import traceback
import select
from os.path import splitext

HOST = 'localhost'
PORT = 8000
BUFSIZ = 1024
ADDR = (HOST, PORT)

# context
socketMap = {}
requestMap = {}
r, w, e = [], [], []

# setting server socket
serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serverSocket.bind(ADDR)
serverSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
serverSocket.listen(100)

class Request(object):
def __init__(self, message):
headers = {}
try:
message = message.strip().splitlines()
self.start = message[0].strip().split(' ')
for i in range(1, len(message)):
line = message[i]
if line.strip() != '':
index = line.index(':')
key = line[0: index]
value = line[index + 1:]
headers[key] = value
except IndexError, e:
pass
self.headers = headers

def method(self):
return self.start[0]

def url(self):
return self.start[1]

def version(self):
return self.start[2]

def handler(req, reqClnt):
try:
path = '.' + req.url()
ext = splitext(path)
if ext[1] == '':
f = os.popen('python ' + path + '.py')
reqClnt.send('\n'.join(f.readlines()))
f.close()
else:
f = open('.' + req.url())
reqClnt.send('\n'.join(f.readlines()))
f.close()
except IOError, e:
reqClnt.send(str(e))

socketFileno = serverSocket.fileno()
socketMap[socketFileno] = serverSocket
print 'start socket ', socketFileno, '*' * 50

try:
while True:
r, w, e = [], [], []
for fd in socketMap:
r.append(fd)
w.append(fd)
e.append(fd)
r, w, e = select.select(r, w, e, 1)
for fd in r:
isocket = socketMap[fd]
if fd == socketFileno:
print 'accepting...........'
clientSock, clientAddr = isocket.accept()
print 'connection from ', clientAddr
clientFileno = clientSock.fileno()
r.append(clientFileno)
w.append(clientFileno)
e.append(clientFileno)
socketMap[clientFileno] = clientSock
else:
print 'reading............'
requestMap[fd] = Request(isocket.recv(BUFSIZ))

for fd in w:
try:
req = requestMap[fd]
except KeyError, e:
pass
else:
print 'writing.............'
osocket = socketMap[fd]
handler(req, osocket)
del requestMap[fd]

for fd in e:
esocket = socketMap[fd]
print 'socket close ', fd
esocket.close()
del socketMap[fd]
print 'no data coming'

except Exception, e:
print traceback.print_exc()
serverSocket.close()
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: