import socket
import re
import os
import sys # 由于前面太繁琐,可以用类封装一下,也可以分几个模块
class HttpServer(object): def __init__(self,port):
# 1、服务器创建负责监听的socket
self.socket_watch = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2、设置地址重用
self.socket_watch.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# 3、绑定监听的端口
self.socket_watch.bind(('', port))
# 4、设置监听队列
self.socket_watch.listen(128) def handle_client(self,socket_con):
"""
接收来自客户端的请求,并接收请求报文,解析,返回
"""
# 1、服务器接收客户端的请求报文
request = socket_con.recv(4096).decode() # 2、截取请求报文,获取请求行
request_lines = request.split("\r\n")
# 3、获取请求行
request_line = request_lines[0]
# GET /a/ab/c.html HTTP/1.1
# 通过正则表达式 匹配出请求行中请求资源路径
res = re.match(r"\w+\s+(\S+)",request_line)
# 获取资源路径
path = res.group(1)
# 将资源路径和我的web文件夹的绝对路径拼接(自己填写)
path ="# 本地绝对路径" + path
# 在判断是文件还是文件夹之前,首先要判断你这个路径在服务器中是否存在
if not os.path.exists(path):
response_line = 'HTTP/1.1 404 Not Found\r\n'
response_head = 'Server:skylark 2.0\r\n'
response_head += 'Content-type:text/html;charset=utf-8\r\n'
response_body = '你请求'+ path +'不存在'
response = response_line + response_head + '\r\n' +response_body
socket_con.send(response.encode())
socket_con.close()
return
else:
# 判断用户请求的是文件还是文件夹
if os.path.isfile(path):
# 如果文件存在 读取页面数据,然后返回
response_line = "HTTP/1.1 200 OK\r\n"
response_head = "Server:skylark 2.0\r\n"
# 注意请求图片需要使用"rb"的方式进行读取
file = open(path,"rb")
# response_body 是二进制所以不用再次编码
response_body = file.read()
response = response_line.encode() + response_head.encode() +"\r\n".encode() +response_body
socket_con.send(response)
socket_con.close()
return
else:
if path.endswith("/"):
# 例如 www.baidu.com/images
# 用户请求的文件夹
# 1、判断该文件夹下是否有默认的文件,如果有,则返回,如果没有
# index.html default.html
default_document = False
# 如果允许你访问我目录下的默认文档
if default_document:
# 判断用户访问的文件夹下是否有index.html 或者 default.html
if os.path.exists(path + '/index.html'):
response_line = 'HTTP/1.1 200 OK\r\n'
response_head = 'Server:skylark 2.0\r\n'
file = open(path+'/index.html', 'rb')
response_body = file.read()
response = response_line.encode() + response_head.encode() +'\r\n'.encode()+response_body
socket_con.send(response)
socket_con.close()
return
elif os.path.exists(path + '/default.html'):
response_line = 'HTTP/1.1 200 OK\r\n'
response_head = 'Server:skylark 2.0\r\n'
file = open(path + '/default.html', 'rb')
response_body = file.read()
response = response_line.encode() + response_head.encode() + '\r\n'.encode() + response_body
socket_con.send(response)
socket_con.close()
return
else:
# 访问的目录下,既没有index.html 也没有default.html
response_line = 'HTTP/1.1 404 Not Found\r\n'
response_head = 'Server:skylark 2.0\r\n'
response_head += 'Content-Type:text/html;charset=utf-8\r\n'
response_body = 'index.html 或者 default.html 不存在'
response = response_line +response_head +'\r\n' +response_body
socket_con.send(response.encode())
socket_con.close()
# 2、判断服务器是否开启了目录浏览
else:
# 判断你是否开启了目录浏览
dir_browsing = True
if dir_browsing:
# 把用户请求的文件夹中所有的文件和文件夹以目录的形式返回到页面中
# 获取用户请求的文件夹
list_names = os.listdir(path)
response_line = 'HTTP/1.1 200 OK\r\n'
response_head = 'Server:skylark 2.0\r\n'
# 动态的拼接页面,将目录中的文件或者文件夹的名称以HTML页面的方式返回给浏览器
response_body = '<html><head><body><ul>'
for item in list_names:
response_body +="<li><a href = '#'>"+item+"</a></li>"
response_body+='</ul></body></head></html>'
response =response_line + response_head +'\r\n' +response_body
socket_con.send(response.encode())
socket_con.close()
return else:
# 用户请求的路径没有斜线
# 重定向到+斜线的目录下
response_line = 'HTTP/1.1 302 Found\r\n'
response_head = 'Server:skylark 2.0\r\n'
response_body = 'redirect'+ path +'/'
response = response_line +response_head +'\r\n' +response_body
socket_con.send(response.encode())
socket_con.close() def run_server(self):
# 5、通过循环,不停的接收来自客户端的连接请求
while True:
socket_con, con_adds = self.socket_watch.accept()
# 注意将con_adds转成字符串
print('客户端:%s连接成功!!!' % str(con_adds))
# 接收来自客户端的请求,并接收请求报文,解析,返回
self.handle_client(socket_con) def main():
# sys.argv方法的用法如下:
# 在终端输入 python3 面向对象封装的web服务器.py 8888
# 在使用解释器执行任意py文件的时候,可以传入不止一个参数,会以字符串的形式用列表保存起来
# 但是列表的第一个参数[0]位是它自己。所以传入的参数是从[1]第二位开始的
# 所以在上面输入8888以后,调取这个列表的[1]下标就会传入这个8888作为进到下面的代码
# 再转换一下类型为int就相当于用户指定端口了
port = int(sys.argv[1])
http_server = HttpServer(port)
http_server.run_server() if __name__ == '__main__':
main()

  

面向对象封装的web服务器的更多相关文章

  1. Node.js学习笔记(五) --- 使用Node.js搭建Web服务器

    1. Node.js 创建的第一个应用 1.引入http模块 var http = require("http"); 2. 创建服务器接下来我们使用 http.createServ ...

  2. 01-静态web服务器(Python)-面向对象的对比

    普通写法,静态web服务器: 先创建TCP服务器套接字,然后等待客户端(这里是浏览器)请求连接. 客户端发起请求,用线程来处理连接的建立,这样可以实现多任务(也就是并发) 连接后根据请求发送指定页面 ...

  3. 利用Python实现对Web服务器的目录探测

    今天是一篇提升技能的干货分享,操作性较强,适用于中级水平的小伙伴,文章阅读用时约3分钟. PART 1/Python Python是一种解释型.面向对象.动态数据类型的高级程序设计语言. Python ...

  4. 利用 python 实现对web服务器的目录探测

    一.pythonPython是一种解释型.面向对象.动态数据类型的高级程序设计语言.python 是一门简单易学的语言,并且功能强大也很灵活,在渗透测试中的应用广泛,让我们一起打造属于自己的渗透测试工 ...

  5. JavaSE 手写 Web 服务器(一)

    原文地址:JavaSE 手写 Web 服务器(一) 博客地址:http://www.extlight.com 一.背景 某日,在 Java 技术群中看到网友讨论 tomcat 容器相关内容,然后想到自 ...

  6. 一不小心写了个WEB服务器

    开场 Web服务器是啥玩意? 是那个托管了我的网站的机器么? No,虽然那个也是服务器,但是我们今天要说的Web服务器主要是指像IIS这样一类的,用于处理request并返回response的工具,没 ...

  7. 自己实现一个简易web服务器

    一个web服务器是网络应用中最基础的环节. 构建需要理解三个内容: 1.http协议 2.socket类 3.服务端实现原理 1.1 HTTP http请求 一般一个http请求包括以下三个部分: 1 ...

  8. 关于Web服务器的认识

    马上就要毕业了,也要开始找工作了,大学写了这么多代码了,却没有好好总结一下常用的概念很是遗憾额,就通过这篇博客记录一下我最常用的一些知识好了. 说到Web服务器,有很多文章都介绍的很好,之前看到一篇非 ...

  9. 自己动手模拟开发一个简单的Web服务器

    开篇:每当我们将开发好的ASP.NET网站部署到IIS服务器中,在浏览器正常浏览页面时,可曾想过Web服务器是怎么工作的,其原理是什么?“纸上得来终觉浅,绝知此事要躬行”,于是我们自己模拟一个简单的W ...

随机推荐

  1. 深入理解C语言函数指针(转)

    本文转自:http://www.cnblogs.com/windlaughing/archive/2013/04/10/3012012.html 示例1: void myFun(int x); //声 ...

  2. PHP+jQuery实现翻板抽奖(中奖概率算法)

    在电视节目中有一种抽奖形式暂且叫做翻板抽奖,台上有一个墙面,墙面放置几个大方块,主持人或者抽奖者翻开对应的方块即可揭晓中奖结果.类似的抽奖形式还可以应用在WEB中,本文将使用PHP+jQuery为您讲 ...

  3. Video 视频播放防作弊和禁止下载

    1.实现效果 - 查看源码 实现视频可播放不能下载,禁止右键下载.F12源码打开链接下载 实现只在当前窗口播放,切换窗口.窗口最小化.窗口被遮挡停止播放,恢复后继续播放 在线demo:缓存完再播放 . ...

  4. C#多线程进度条

    public class ZyjProgressBar : System.Windows.Forms.ProgressBar { //用于跨线程访问控件的委托 private delegate voi ...

  5. Windows之CMD查看系统信息

    Windows 系统通过命令行(CMD)查询系统信息有两种方式: 1.图形化界面: 在“运行”中键入CMD,然后输入 dxdiag,回车后弹出图形化界面 ------ DirectX 诊断工具. 2. ...

  6. .net函数

    Math.Ceiling() Math.Floor() == 向上取整,向下取整 Regex.Split(productListControl.Text, "\n", RegexO ...

  7. cocos2d-x游戏之2048

    学习游戏编程是一件非常有趣的事情,在cocos2dx官网找了几个简单的游戏试试手,感觉也不是那么难,首先来看看2048这款游戏吧,很火的原因之一是因为它简单而易操作.网上这位Legendof1991大 ...

  8. sharepoint2010的几个类型字段赋值和取值的方法

    1.日期类型查询,需要转换,方法如下: //转换时间 string startdate = SPUtility.CreateISO8601DateTimeFromSystemDateTime(Date ...

  9. mysql在控制台里出现中文问号问题

    由于重装了wampserver,之前遇到的问题统统会重新出现,那么今天遇到的是在mysql控制台中,在表里输入中文数据,却出现问号的问题: 那么这个就跟编码有关系了,那么,我们就去wampserver ...

  10. April 9 2017 Week 15 Sunday

    In the evening one may praise the day. 入夜方能赞美白昼. I think that could be understand in different ways, ...