栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

Python实现简单的Web服务器 Part1

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Python实现简单的Web服务器 Part1

这篇文章想写得是一个简单的web服务器。

首先可能需要了解一点网络编程,web服务器,简单的说,运行在一台机器上的一个进程(通常不在本地),浏览器也是运行在机器上的一个进程(本地的)。也就是说,他的本质其实就是一个跨机器的进程通信。

然后,实现了跨机器的通信之后,服务器和浏览器通信的数据格式,其实就是http协议。也就是说,浏览器和服务器必须按照http协议规定的格式发送数据,要不然的话,对方就听不懂了。

关于网络编程的知识,你可以参考:
http://www.jianshu.com/p/8f1941c4a549

关于http协议的知识,你可以参考:
超简洁的实例 ——关于HTTP协议分析 http://www.jianshu.com/p/f5a5db039737

关于实现一个web服务器

初步的功能是这样,运行服务器之后,在局域网内的设备可以访问这个服务器。比如,我在服务器下面放了一个class.html 文件,这是我的课表。当我用手机访问这个网页的时候,在手机的浏览器中显示这个页面。如下图:(随便写得一个html文件,虽然丑,但是模拟一下这个功能就好)


局域网内手机访问.png

pc访问.png

这篇文章只写了一个静态的web服务器,下一篇文章写了 模拟实现cgi,支持脚本语言:
Python实现简单的Web服务器 Part2
http://www.jianshu.com/p/d28395655bc0

python 下有一个库baseHTTPServer,这个库封装了一个常用的处理http协议的请求和响应的函数,如果用这个库,基本上就不需要考虑网络层的实现了,只需要了解http协议就好。

但是也可以从网络层写起,利用socket编程。这样你需要考虑的一个很重要的问题就是:服务器处理并发,是多线程还是多进程,还是异步模型,或者是多进程+多线程。现在感觉网络编程真的是博大精深。

这样一个最简单的服务器就写好了,但是他不能对浏览器请求的页面做出响应,对于所有的请求,服务器回复 “to-do”

import baseHTTPServer#RequestHandler 繼承 baseHTTPRequestHandler class RequestHandler(baseHTTPServer.baseHTTPRequestHandler):
    '''处理请求并返回页面'''
    # 页面模板
    Page = "to do "
    #do_GET的函數的名字 是不能改的
    def do_GET(self):
        self.send_response(200)
        self.send_header("Content-Type", "text/html")
        self.send_header("Content-Length", str(len(self.Page)))
        self.end_headers()
        self.wfile.write(self.Page)if __name__ == '__main__':
    serverAddress = ('', 8080)
    server = baseHTTPServer.HTTPServer(serverAddress, RequestHandler)
    server.serve_forever()

demo2 依然不可以响应不同的html文件请求,但是可以利用基类的数据成员来输出http请求的时间,端口,请求的html文件。

#-*- coding:utf-8 -*-import baseHTTPServer#RequestHandler 繼承 baseHTTPRequestHandler ,所以他自身就有一個path的數據成員class RequestHandler(baseHTTPServer.baseHTTPRequestHandler):
    #Page="to doing  wakakak "
    Page='''
    
    
    
                         
            
            
           
                    
                          
    
HeaderValue
Date and time{date_time}
Client host{client_host}
Client port{client_port}
Command{command}
Path{path}
              '''     #     def do_GET(self):        #self.send_response(200)         #self.send_header('Content-Type','text/html')         #self.send_header('Content-Length',str(len(self.Page)))         #self.end_headers()         #self.wfile.write(self.Page)         page=self.create_page()        self.send_content(page)    def send_content(self,page):        self.send_response(200)        self.send_header('Content-Type','text/html')        self.send_header('Content-Length','text.html')        self.end_headers()        self.wfile.write(page)    #self.date_time_string 和 client_address[0/1]等等都是父類的書據成員     def create_page(self):         values={            'date_time':self.date_time_string(),            'client_host':self.client_address[0],            'client_port':self.client_address[1],            'command':self.command,            'path':self.path         }         page=self.Page.format(**values)        return pageif __name__ == '__main__':     serverAddress = ('', 8080)     server = baseHTTPServer.HTTPServer(serverAddress, RequestHandler)     server.serve_forever()

运行结果:


image.png

对于html 请求的响应,其实就是拿去这个url请求后面的路径,然后在服务器的目录下面去找这个文件,如果有,就返回给浏览器。如果没有,就返回404状态码。

下面是demo3:

#coding:utf-8import sys,os,baseHTTPServerclass ServerException(Exception):
    pass#RequestHandler 繼承 baseHTTPRequestHandler ,所以他自身就有一個path的數據成員class RequestHandler(baseHTTPServer.baseHTTPRequestHandler):
    Error_Page="""
    
    
    Error accessing {path}
    

{msg}

              """     def do_GET(self):         try:            print 'get'             full_path=os.getcwd()+self.path            print full_path            print os.getcwd()            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("unkown object '{ 0 }'",format(self.path))        except Exception as msg:             self.handle_error(msg)    def handle_file(self,full_path):         try:            with open(full_path,'rb') as reader:                 content=reader.read()             self.send_content(content)        except IOError as msg:             msg="'{0}' cannot be read :{1} ".format(self.path,msg)             self.handle_error(msg)    def handle_error(self,msg):         content=self.Error_Page.format(path=self.path,msg=msg)         self.send_content(content,404)    def send_content(self,page,status=200):         #print 'send_content function '         self.send_response(status)         self.send_header('Content-Type','text/html')         self.send_header('Content-Length','text.html')         self.end_headers()         self.wfile.write(page)if __name__ == '__main__':     serverAddress = ('', 8081)     server = baseHTTPServer.HTTPServer(serverAddress, RequestHandler)     server.serve_forever()

运行结果就是第一张图那法样,实现了一个简单的静态服务器。
git链接:https://github.com/zhaozhengcoder/Python

下一步,试着去模拟实现一些cgi
//to-do 吃饭去了 好饿
后续可以参考:
Python实现简单的Web服务器 Part2 http://www.jianshu.com/p/d28395655bc0


作者:sexycoder
链接:https://www.jianshu.com/p/2fc93de02b94


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/224901.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号