tips: 功能:实现多用户访问服务器
准备:本地html文件(代码中文件相对路径要根据实际情况更改)
难点:
用select实现多路复用
对select语句的理解(数据发送完及时关闭套接字并移出List)
#coding=utf-8
from socket import *
import select
import re
#0定义函数:从浏览器的请求数据找出要读的本地文件地址
def findFileAddr(data):
reResult = re.match(r'GET /(.*)\sHTTP/1.1',data).group(1)
#如果匹配不到即跳转到默认网址
if not reResult:
return './html/index.html'
else:
#如果匹配到图片格式就从正则出img文件名,然后在img文件夹中找
if re.match(r'images/.*\.png',reResult):
return './html/'+re.match(r'images/.*\.png',reResult).group()
else:
return './html/'+reResult
def main():
#1建立服务器
serv = socket(AF_INET,SOCK_STREAM)
serv.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
loaclAddr = ('',80)
serv.bind(loaclAddr)
serv.listen(2)
print'--------------服务器正在监听中---------------------------'
#2采用select实现多路复发
responceHeader = '''HTTP/1.1 200 OK Content-Type:text/html\r\n\r\n'''
readList = [serv,]
while True:
readableList,writebleList,exception = select.select(readList,[],[])
for temp in readableList:
if temp == serv:
newsocket,destAddr = serv.accept()
print str(destAddr)+'已连接'
readList.append(newsocket)
else:
request = temp.recv(1024)
if request:
#从浏览器发送的请求文件里面找出本地文件地址
fileAddr = findFileAddr(request)
f = open(fileAddr,'r')
sendData = responceHeader+f.read()
temp.send(sendData)
#发送完立马关掉并移出列表
temp.close()
readList.remove(temp)
print'请求数据已发送'
else:
print'该用户已下线'
temp.close()
readList.remove(temp)
if __name__ == '__main__':
main()