要想实现web服务器,首先要明白web服务器应该具备怎样的功能:比如说浏览器发送了http请求(GET或POST),服务器要首先接收客户端发送的TCP请求,与之建立链接,然后接收http请求,解析并响应。 之后就是客户端的事情了,客户端接受响应并解析,显示,之后服务器断开链接。

为了能很好地理解上面这个过程,我分别查询了以下概念:

1. HTTP协议

浏览器的页面中包含CSS,html,JavaScript,视频文件、图片文件等等。我的理解就是html协议规定了网页元素的表达,一个html文件可以视为用编程语言写出来的网页内容。而html本身也指这个规定本身。

而互联网的概念是:所有设备都提供独特的标签(总称互联网协议地址或IP地址),有互联网服务供应商(ISP)提供的公网IP地址,通过这些地址,可以进行通信。

如下图:

2. web服务器的基本概念,包括链接建立后的传输过程

这时候,我们对整个过程有了大致的了解,要对其进行实现我们需要做瑞星啊几件事:

* 接受TCP请求可使用http.server库来自动完成(注意,python3使用这个库,但是实验楼里用python2.7用的是另一个库)。

伪代码如下:

其中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请求和响应的格式:

3. 实现静态页面

接下来按照我实验时的步骤来分别记录。

步骤1. 首先建立一个简单web服务器, 能够响应静态页面

首先在主函数中,固定的使用以下语句即可:

这里url地址空缺则代表本机地址127.0.0.1,端口可以改动(有些端口系统占用着)。

所以为了让上述代码运行起来,我们的主要内容在于实现RequestHandler。

之前提到过,使用BaseHTTPRequestHandler,则需要定义一个子类,并在子类中给出do_GET(),页面设计等内容。如下代码所示,我们在该类中给出依照http响应的格式写出的内容,再在do_GET()函数中将该内容作为响应返回。相当于我们在RequestHandler类中给出了http的响应。

而我们同样要判断在什么样的情况下我们给出上述响应,同时处理不合理的请求和异常。

因此接下来我们要写do_GET()的具体逻辑和代码,假设静态页面存在了plain.html中,那么合理的url是127.0.0.1:8030/plain.html,而其对于他的请求服务器是不能做出反应的。所以do_GET()的重点在于判断输入合理与否:我们将输入分为三种情况:路径不存在、路径不是一个文件、路径是一个文件。

这里的异常是异常中基类Exception的子类,即

里面什么都不干,但是利用Exception我们可以对异常报相应的错误信息。raise 语句中括号中就是异常的提示信息。

这里用到了字符串的format方法,format是格式化输出的方法,即最终显示的是format括号内的内容代替中的内容后的字符串内容。当然format的用法还有更为复杂的形式,如后面会见到的“”.format(**字典),这个语句中有另外一个知识点,**dict。**dict作为函数的参数时,是用键值对应函数中的参数名,而用值作为函数的输入值。而在字符串.format中,用字典的键匹配字符串中{}里的内容,而用值去依次替换,如

有关文件路径:

#获取文件路径 fullpath = os.getcwd() + self.path (+号前得到当前路径,后面是得到handler得到的路径,如/plain.html

处理并显示内容

#从文件中得到内容 content = file.read() (注意content此处需要字符串,所以open('r')以r方式而非rb,rb读入是byte类型。

这里需要说明下,python3.6对于字符串还是byte有明确区分,所以读入时要用'r' 还是‘rb’要注意。之前有关python项目中也提到过这个问题。

以上内容都了解后,我们就可以实现出一个响应静态页面的服务器,当然,你需要有plain.html文件放在和你python代码的相同目录下。你可以在https://drive.google.com/file/d/0By68FgZpORkFOWZKS1dzeHpfTlk/view?usp=sharing下载得到。

下载httpserver_plain.py文件和plain.html文件即可测试以上介绍的内容。(csdn上传以后不能删除不能修改,这里必须疯狂吐槽)

如何测试?

你可以用cmd打开终端,运行以上python代码(命令为python httpserver_plain.html),之后在浏览器中输入127.0.0.1:你设置的端口号/plain.html.查看效果。

或者pip安装httpie,终端输入http 127.0.0.1:你设置的端口号/plain.html来查看调用效果。

示意代码如下:

4. 当可以响应静态页面之后,我们接着实现CGI协议与脚本。

某些请求可以用另外编写脚本来处理(给出响应),这样对于新增的一些请求,就不用每次都修改服务器脚本了。为了更好地理解CGI,我们需要知道以下基本概念。

与之前实现静态页面相对比,这里实现cgi脚本有何不同?

--> 我们在访问静态页面时,输入127.0.0.1:8030/plain.html,服务器会为我们返回plain.html文件的内容;而cgi脚本我们访问的是一个脚本,即127.0.0.1:8030/time.py,返回的是执行外部命令并获得的输出。

(1. 第一个内容就是如何实现执行外部命令获得该输出

我们使用subprocess库,具体代码是:

(2. 第二个内容是要在if语句中判断是否路径中文件是否以指定后缀结尾可用字符串方法endswith()判断是否以".py"结尾。(该方法以".py"作为参数,输出bool值)

当实现了以上两个功能后,我们只需在类似静态页面的实现那样填补代码逻辑即可,示意代码如下:

注意到主要的区别在于我们在RequestHandler类中实现了run_cgi(self, fullpath),用来从外部执行请求的脚本内容(如这里的time.py);而条件中我们也加入了后缀的判断。

5. 代码整理和重构

(1 .条件类

从上述plain和cgi的两个示意代码中,大家可能已经发现:在对不同条件的判断中,两个代码分别使用了if-elif-else语句形式和条件类的形式。其中前者理解很容易,而后者条件类是指将条件放置在不同的类中,然后循环遍历这些类,看哪个符合则对应执行相应条件。这样处理的好处在于易于维护:对于新加入的条件,不对改动if-elif-else使其变得臃肿,而只需增加一个类作为条件,同时在handler中循环遍历即可。

如我们要增加一个功能:在输入127.0.0.1:端口号时,我们希望得到主页的显示(存为index.html),这时我们就新建一个条件类:

同时在RequestHandler的实现中将其加入:

这样,我们就可以很方便的把新的条件加入进去,同时管理维护起来也很方便。该代码的实现也在上述链接中可以下载,包含两个文件:httpserver_index.py和index.html。

(2. 代码重构

这里的重构主要针对每个条件类中重复过的代码,我们可以通过构建基类,然后生成条件类时作为基类的子类生成即可,从而更好地维护代码。具体实现如下:

里面对test和act的定义是通过断言来实现的,内在逻辑是:如果你子类不实现这两个方法, 那么你生成的子类是一定会出错的。于是这相当于是限定子类必须实现这两种方法。之后子类继承该基类即可:

但是handle_file就不需要在RequestHandler中实现了,因为基类中已经包含了。该代码在连接中名为httpserver_baseclass.py。

以上就是我做实验楼实验的整个笔记,从一开始BaseHTTPServer模块import出错,找python3中的对应模块,到学习新模块,依次完成实验内容,中间有一些py2、3的不同的小坑,但是学完之后还是有不少收获。

6.这里我在将学到的内容总结一下:

(1.http协议

浏览器的页面中包含CSS,html,JavaScript,视频文件、图片文件等等。我的理解就是html协议规定了网页元素的表达,一个html文件可以视为用编程语言写出来的网页内容。而html本身也指这个规定本身。

而互联网的概念是:所有设备都提供独特的标签(总称互联网协议地址或IP地址),有互联网服务供应商(ISP)提供的公网IP地址,通过这些地址,可以进行通信。

如下图:

(2. web服务器的基本概念,包括链接建立后的传输过程

(3. http请求格式

(4.http响应格式

(5. httpie库

可以使用httpie库代替浏览器发送请求

安装命令是 pip install httpie,

使用命令是:http 网址(url)

(6. http.server库

整个web服务器实现都是在使用这个库,他替我们解决tcp链接,请求解析等很多内容,我们只需要实现RequestHandler类的处理逻辑编写(这里也只涉及到了do_GET).

(7.socket模块

socket套接字是做什么用的?-->两个端点的程序之间的“信息通道”。即计算机1中的程序与计算机2中的程序通过socket发送信息。套接字是一个类,一个套接字是socket模块中的socket类中的一个实例。一个套接字处理一次通讯(服务器和客户机),各自进行设置,对应有不同的方法,比如说,s.connect就是客户机,s.listen(5)就是服务器。

连接方式在于一个connect(),一个listen(),使用accept()方法来完成。(accept()是服务器端开始监听后,可以接受客户端的连接。)accept返回(client,address)元祖,client是客户端套接字,而address是地址。处理完与该客户端的连接后,再次调用accept方法开始等待下一个连接。

(8.CGI

(1)字符串format方法

(2)**dict

(3)str/byte转换

(9. os库

(10. subprocess库

如何实现执行外部命令获得该输出

我们使用subprocess库,具体代码是:

(11. 写基类,不鸡肋

python新手练习项目_最适合新手练习的Python小项目!还是有难度的!用了五天整理...相关推荐

  1. python入门新手项目-Python入门实战项目有哪些适合新手?

    Python入门实战项目有哪些适合新手?目前市面上有很多适合新手的Python入门练手项目,Python入门需要理论与实践相结合,前面夯实基础知识,后面通过实战项目帮助你更好的运用这些Python知识 ...

  2. steam/csgo搬砖项目,非常适合新手小白

    Steam平台是一个游戏平台,可以在上面交易游戏物品.Steam搬砖就是在steam平台购买饰品,去国内网易buff平台售卖.Steam搬砖的利润是月利润30%左右 饰品的市场需求: 1. steam ...

  3. 在家做什么可以赚钱?适合在家的5个小项目!

    想要在家就可以做一些兼职来获得收入,有什么样的兼职比较适合呢?处在互联网时代的我们只要你拥有电脑和手机就可以兼职赚钱,但是网上有很多兼职都是骗人的,为了防止自己被骗,最好找一些正规靠谱的平台.天上没有 ...

  4. java吃货联盟系统源码_小项目,吃货联盟,java初级小项目,源代码

    小项目,吃货联盟,java初级小项目,源代码 1importjava.util.Scanner;23/**4* 吃货联盟订餐管理系统5*6*/7publicclassOrderingMsg {8pub ...

  5. 8个适合新手入门的python项目2020_8个适合新手入门的Python项目(2020.6)

    这是一个针对新浪的爬虫脚本,并且实时更新 这是一个包含了人脸识别.轮廓识别.头像合成.视频对象提取.图片自动上色.眼动追踪.换脸等功能的人脸ai开源项目. 这是一个由google开发的开源图像识别工具 ...

  6. externalreferences 命令在 sdi 模式下不可用_一个适合新手交互式Git命令学习项目

    前言 在我们日常工作开发中,Git是必不可少的版本控制软件,很多时候我们都用Git来管理我们的项目. 比较常用的有Github,Gitlab,Stash等. 因此对于Git命令的掌握是我们工作必备的能 ...

  7. 支持所有库的python手机编程软件_有了这个软件,Python新手可以随时随地用手机练习编程了...

    很多小伙伴想利用空闲时间学习Python,但是有时候身边没有电脑,今天就给大家推荐一款手机APP:QPython. Qpython是一个Python引擎,只能运行在安卓系统上,内置了一个Python编 ...

  8. python迷你停车管理系统_建议收藏,22个Python迷你项目(附源码)

    在使用Python的过程中,我最喜欢的就是Python的各种第三方库,能够完成很多操作. 下面就给大家介绍22个通过Python构建的项目,以此来学习Python编程. 大家也可根据项目的目的及提示, ...

  9. python玫瑰手绘_两个撩妹的python项目

    这两天刷爆朋友圈的莫过于一则「啥是佩奇」的视频短片,看完之后不由的感叹一句,好久没见过这么温情幽默的广告了! 作为一个python的学习者,让我萌生了用python画社会人的想法. 看这个图像可以发现 ...

最新文章

  1. 开发者转型AI看过来,这是一场汇聚中美顶尖专家的AI盛会
  2. 不可错过的 GAN 资源:教程、视频、代码实现、89 篇论文下载
  3. 带着问题读CLR via C#(六)常量与字段
  4. SAP ABAP STOP,EXIT,CHECK,RETURN
  5. 目前计算机硬件安全,计算机硬件策划安全问题若干研究论述.doc
  6. Android 高级Drawable资源---复合Drawable----状态列表Drawable
  7. php 缺少 wordpress,Wordpress localhost安装错误 - 您的PHP安装似乎缺少WordPress所需的MySQL扩展程序...
  8. 利用python数据分析panda学习笔记之Series
  9. Sqoop的安装配置及工作机制
  10. 华科PAMI黑科技,方向任意目标检测新算法
  11. CSS 参考资料/学习资料
  12. Signature字段
  13. java为什么序列化_什么是Java序列化、为什么要序列化、JAVA序列化有哪些方式(性能由低至高)...
  14. Magic Swf2Gif(SWF转换GIF)绿色汉化版 V1.35
  15. 机器学习原理与实践(开源图书)-总目录
  16. 听说,Java程序员都是吃青春饭的?
  17. oracle之Number类型小数转字符串丢精度
  18. 阿里云ACP如何线上考试
  19. 5. Longest Palindromic Substring
  20. UTC与BJT时间换算C语言

热门文章

  1. 贝塞尔曲线与CSS3动画、SVG和canvas的基情
  2. 产品经理必备数据统计网站汇总
  3. iOS 5.1 不完美越狱工具发布
  4. linux发布java程序docker(一)
  5. RabbitMQ官方文档知识点总结合集+代码注释(中文+Java版)
  6. 滚球经验总结(PID)
  7. uniapp Android 离线打包之未配置appkey或配置错误
  8. 【Tableau作图思路-可视化】扇形图 - 层叠饼图 镶嵌饼图、圆环 经验分享
  9. Java面试题之基础篇
  10. Altera 芯片代码实现远程更新