python实现一个简单的项目_Python小项目四:实现简单的web服务器
本博客是整理在学习实验楼的课程过程中记录下的笔记形成的,参考:https://www.shiyanlou.com/courses/552。不同之处在于实验楼使用python2.7,而博主这里使用的是python3.6。在学习中也因为python版本不同遇到了一些坑,这里写成博客一作记录,二来可以帮助像博主这样的入门者少踩一些坑。
要想实现web服务器,首先要明白web服务器应该具备怎样的功能:比如说浏览器发送了http请求(GET或POST),服务器要首先接收客户端发送的TCP请求,与之建立链接,然后接收http请求,解析并响应。 之后就是客户端的事情了,客户端接受响应并解析,显示,之后服务器断开链接。
为了能很好地理解上面这个过程,我分别查询了以下概念:
1. HTTP协议
对于 http://www.google.com 这个网址,我们叫url,而http则是服务于url的协议。另外,url和ip地址两者的一一对应是通过DNS(域名解析系统)来完成的。
浏览器的页面中包含CSS,html,JavaScript,视频文件、图片文件等等。我的理解就是html协议规定了网页元素的表达,一个html文件可以视为用编程语言写出来的网页内容。而html本身也指这个规定本身。
而互联网的概念是:所有设备都提供独特的标签(总称互联网协议地址或IP地址),有互联网服务供应商(ISP)提供的公网IP地址,通过这些地址,可以进行通信。
如下图:
2. web服务器的基本概念,包括链接建立后的传输过程
这时候,我们对整个过程有了大致的了解,要对其进行实现我们需要做瑞星啊几件事:
* 接受TCP请求可使用http.server库来自动完成(注意,python3使用这个库,但是实验楼里用python2.7用的是另一个库)。
伪代码如下:
from http.server import HTTPServer, 某个handler类
httpd = HTTPServer( url地址, handler类)
其中HTTPServer作用是创建并监听HTTP socket,解析请求给handler类。url地址即服务器url,handler类在http.server中有三种,这里用BaseHTTPRequestHandler,该类本身不能响应任何实际的HTTP请求,因此需要定义子类来处理每个请求方法(GET/POST),实际上就是空的handler类,允许用户自定义处理方法。
在本次实验中值处理GET请求——相应的在子类中定义(给出)do_GET()函数即可。
上面内容中也提到了socket,为了更好地理解我也查询了相关内容。注意python中的大部分网络编程模块都隐藏了socket模块的细节,不直接和套接字交互。所以这里我们只需要理解即可,具体编程不需要考虑其中内容。
socket套接字是做什么用的?-->两个端点的程序之间的“信息通道”。即计算机1中的程序与计算机2中的程序通过socket发送信息。套接字是一个类,一个套接字是socket模块中的socket类中的一个实例。一个套接字处理一次通讯(服务器和客户机),各自进行设置,对应有不同的方法,比如说,s.connect就是客户机,s.listen(5)就是服务器。
连接方式在于一个connect(),一个listen(),使用accept()方法来完成。(accept()是服务器端开始监听后,可以接受客户端的连接。)accept返回(client,address)元祖,client是客户端套接字,而address是地址。处理完与该客户端的连接后,再次调用accept方法开始等待下一个连接。
总结来说,在这个实验里,我们要实现的功能只是根据用户的请求,生成http响应。所以我们也应该知道http请求和响应的格式:
接下来按照我实验时的步骤来分别记录。
步骤1. 首先建立一个简单web服务器, 能够响应静态页面
首先在主函数中,固定的使用以下语句即可:
if __name__ == '__main__':
httpAddress = ('', 8030)
httpd = hs.HTTPServer(httpAddress, RequestHandler)
httpd.serve_forever()
这里url地址空缺则代表本机地址127.0.0.1,端口可以改动(有些端口系统占用着)。
所以为了让上述代码运行起来,我们的主要内容在于实现RequestHandler。
之前提到过,使用BaseHTTPRequestHandler,则需要定义一个子类,并在子类中给出do_GET(),页面设计等内容。如下代码所示,我们在该类中给出依照http响应的格式写出的内容,再在do_GET()函数中将该内容作为响应返回。相当于我们在RequestHandler类中给出了http的响应。
class RequestHandler(hs.BaseHTTPRequestHandler):
def send_content(self, page, status = 200):
self.send_response(status)
self.send_header("Content-type", "text/html")
self.send_header("Content-Length", str(len(page)))
self.end_headers()
self.wfile.write(bytes(page, encoding = 'utf-8'))
#print(page)
def do_GET(self):
获取路径,
执行操作(send_content)而我们同样要判断在什么样的情况下我们给出上述响应,同时处理不合理的请求和异常。
因此接下来我们要写do_GET()的具体逻辑和代码,假设静态页面存在了plain.html中,那么合理的url是127.0.0.1:8030/plain.html,而其对于他的请求服务器是不能做出反应的。所以do_GET()的重点在于判断输入合理与否:我们将输入分为三种情况:路径不存在、路径不是一个文件、路径是一个文件。
def do_GET(self):
#这里要处理两个异常,一个是读入路径时可能出现的异常,一个是读入路径后若不是文件,要作为异常处理
try:
#获取文件路径
full_path = os.getcwd() + self.path
# 如果路径不存在
if not os.path.exists(full_path):
raise ServerException("'{0}' not found".format(self.path))
#如果该路径是一个文件
elif os.path.isfile(full_path):
self.handle_file(full_path)
#如果该路径不是一个文件
else:
raise ServerException("Unknown object '{0}'".format(self.path))
except Exception as msg:
self.handle_error(msg)这里的异常是异常中基类Exception的子类,即
class ServerException(Exception):
'''服务器内部错误'''
pass里面什么都不干,但是利用Exception我们可以对异常报相应的错误信息。raise 语句中括号中就是异常的提示信息。
/* 这里
"Unknown object '{0}'".format(self.path)
用到了字符串的format方法,format是格式化输出的方法,即最终显示的是format括号内的内容代替{0}中的内容后的字符串内容。当然format的用法还有更为复杂的形式,如后面会见到的“”.format(**字典),这个语句中有另外一个知识点,**dict。**dict作为函数的参数时,是用键值对应函数中的参数名,而用值作为函数的输入值。而在字符串.format中,用字典的键匹配字符串中{}里的内容,而用值去依次替换,如
d = {'x':1, 'y':2}
str = “Pages show {x} and {y}”
print(str.format(**d))
#将显示Pages show 1 and 2*/
有关文件路径:
#获取文件路径 fullpath = os.getcwd() + self.path (+号前得到当前路径,后面是得到handler得到的路径,如/plain.html
#判断路径是否存在 os.path.exist(fullpath)
#判断路径是否是文件 os.path.isfile(fullpath)
处理并显示内容
#从文件中得到内容 content = file.read() (注意content此处需要字符串,所以open('r')以r方式而非rb,rb读入是byte类型。
/* 这里需要说明下,python3.6对于字符串还是byte有明确区分,所以读入时要用'r' 还是‘rb’要注意。之前有关python项目中也提到过这个问题。*/
以上内容都了解后,我们就可以实现出一个响应静态页面的服务器,当然,你需要有plain.html文件放在和你python代码的相同目录下。你可以在我的资源页面下载得到。
下载httpserver_plain.py文件和plain.html文件即可测试以上介绍的内容。
/* 如何测试?
你可以用cmd打开终端,运行以上python代码(命令为python httpserver_plain.html),之后在浏览器中输入127.0.0.1:你设置的端口号/plain.html.查看效果。
或者pip安装httpie,终端输入http 127.0.0.1:你设置的端口号/plain.html来查看调用效果。
*/
(太晚了,明天接着写)
参考:
http://www.cnblogs.com/biyeymyhjob/archive/2012/07/28/2612910.html
http://www.magicsite.cn/blog/web/other/other298023.html
python实现一个简单的项目_Python小项目四:实现简单的web服务器相关推荐
- python实现简单小游戏_用python开发一个有趣的猜数字小游戏(实现简单的GUI界面学习)...
文章目录 用python开发一个有趣的猜数字小游戏 用于字符串的格式化,通过 {} 和 : 来代替以前的 % 1. python的GUI编程 1.1 pythonGUI常用库对比 Python 提供了 ...
- 制作一个有趣的涂鸦物联网小项目(涂鸦模组SDK开发 CBU BK7231N WiFi+蓝牙模组 HSV彩色控制)
实现的功能: l APP控制月球灯 l 本地月球灯控制 l APP控制"大白"颜色,实现各种颜色变身 l 门状态传感器状态APP显示 l 网络状态指示灯,连接服务器长亮, ...
- 网赚网盘赚钱,一个自动来钱的小项目,日入200+!
以往跟大家分享的东西都是一些实操性比较强的,于是就有朋友来问了,说有没有类似像小说项目一样,前期投入进去,后期自动来钱的东西. 喔,想想快要过年了,过年期间很多朋友都是陪在家人身边,可能会缺少精力去打 ...
- python自动填写小程序表单_新年好!教大家用Python写一个自动回复拜年信息的小程序!...
原标题:新年好!教大家用Python写一个自动回复拜年信息的小程序! 过年期间,想必大家都收到很多拜年信息吧!有没有也被拜年短信(大部分是群发)搞得很焦虑?不回复似乎显得很没有礼貌,一一回复又累心劳神 ...
- java qq聊天界面_【附源码】用Java写了一个类QQ界面聊天小项目,可在线聊天!...
原标题:[附源码]用Java写了一个类QQ界面聊天小项目,可在线聊天! 目录: 1.功能实现 2.模块划分 3.使用到知识 4.部分代码实现 5.运行例图 1.功能实现 1.修改功能(密码.昵称.个性 ...
- 用python做一个数据查询软件_Python实现功能简单的数据查询及可视化系统
欢迎点击右上角关注小编,除了分享技术文章之外还有很多福利,私信学习资料可以领取包括不限于Python实战演练.PDF电子文档.面试集锦.学习资料等. image.png 前言 数据时代,数据的多源集成 ...
- Netty - 一个简单的聊天室小项目
经过一段时间对Netty的学习,我们对Netty各版本以及像ProtocolBuffers等技术应用都有了不少相关的了解, 我们就用这段时间学到的只是做一个简单的聊天室的小项目来练习自己学到的技术. ...
- django不修改数据库创外键_python小项目使用django的数据库模型
有时开发一个小项目并不想启动服务,只是在本地运行,但是又有一些数据存储的需求,打算使用数据库.如果直接采用数据库sql语句接口进行操作显得非常麻烦,而且容易出错.现在比较主流的web框架django的 ...
- python练习项目_python练习项目
广告关闭 腾讯云11.11云上盛惠 ,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元! 这是<python基础教程>后面的实践,照着写写,一方面是来熟悉py ...
最新文章
- Babel的配置和使用
- python上机报告出现的问题和解决方法_关于发现存在问题及解决方法的报告
- VC/MFC列表CListCtrl类的LVCOLUMN和LVITEM详解
- python输入数据爬取_python根据用户需求输入想爬取的内容及页数爬取图片方法详解...
- html使标签为正方形,W3C CSS测试答案
- JavaScript学习---JavaScript基础知识
- HTTP Keep-Alive的作用
- Xamarin.Android AlertDialog中的EditText打上去字为什么不显示?也没有光标闪烁
- Windows核心编程_窗口属性表
- 软件可靠性方法 学习笔记
- 百分比布局得应用 —— 模仿京东移动端首页
- GNSS相关开源项目整理
- 涨姿势!2020最好的 10 大国外编程学习网站
- Tipask,Tipask建站,Tipask插件
- win11安装deepin20.6双系统(双硬盘)
- HAL库学习之串口通信
- 高桥盾react和boost_热门对比丨React pk Boost,你更偏向哪一双?
- 新学期,新气象,新起点,新征程。
- NLTK(3)处理文本、分词、词干提取与词形还原
- 使用Coding管理项目代码记录