当前位置: 移动技术网 > IT编程>脚本编程>Python > 用python编写一个web静态服务器(代码教程)

用python编写一个web静态服务器(代码教程)

2018年04月11日  | 移动技术网IT编程  | 我要评论

在一棵树的10m高处有两只猴子,德云社2012封箱,绿巨人2008存档

用python编写一个web静态服务器(代码教程)

\

import socket
import re
from multiprocessing import Process

HOME_DIR = '.\html'


class MyWeb(object):
    """创建web类"""
    def __init__(self):
        """创建server对象"""
        self.server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        # 重复使用绑定的信息
        self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    def bind(self,port):
        """邦定端口号"""
        self.server.bind(('', port))

    def start(self):
        """开始监听客户端的链接"""
        self.server.listen(10)
        while True:
            conn, address = self.server.accept()
            print("客户端[%s]连接进来了" % str(address))
            p = Process(target=self.receive_request, args=(conn,))
            p.start()
            #(1)创建子进程的时候,子进程已经从父进程中复制过了conn,所以可以关闭父进程中的conn了
            conn.close()

    def receive_request(self, conn):
        """接收客户端的链接"""
        request_info = conn.recv(1024).decode()
        #print(request_info)
        self.handle_request(request_info, conn)


    def handle_request(self, request, conn):
        """处理客户端的请求信息"""
        relative_path = request.splitlines()[0].split()[1]
        print(request)
        #(2)
        path = re.sub('/', r'\\', relative_path)
        self.response_info(conn, path)

    def response_info(self, conn, relative_path):
        """将页面返回给浏览器"""
        filename = HOME_DIR+relative_path
        if '\\' == relative_path:
            filename = HOME_DIR+'\'
        print(filename)

        try:
            f = open(filename, 'rb') #(3)有可能是图片,图片为二进制数据
            response_body = f.read()
            f.close()
        except IOError as e:
            response_start = b'HTTP/1.1 400 Not Found\r\n'
            response_head = b'server: localhost\r\n'
            response_body = b'No found the file'
        else:
            response_start = b'HTTP/1.1 200 OK\r\n'
            response_head = b'server: localhost\r\n'
        response_info = response_start+response_head+b'\r\n'+response_body
        conn.send(response_info)
        conn.close()


if __name__ == '__main__':
    my_web = MyWeb()
    my_web.bind(8989)
    my_web.start()

测试:

\

\

解释:

以上就算大概的测试成功了,其中代码中有两处需要注意的地方:

(1)

\

这里关闭conn,是因为创建子进程的时候,子进程已经从父进程中复制过了conn,所以可以关闭父进程中的conn了。

(2)

\

这里文件都用二进制打开,以及二进制的形式组合字符串最好。因为当我们要访问一个html文件时,如里html文件里面有图片的链接地址,图片以二进制打开,不能解码为字符器与响应报文组合了。所以不如一起都是二进制来组合。

(3)我们访问一个页面为什么连了四个客户端?

第一个是获取exc8.html文件

第二个是exc8.html文件中的人物图片的链接地址的访问,所以还会发送一个http请求

第三个也是exc8.html文件中的RESUME的图片地址的访问

第四个是favicon.ico,是浏览器试图获取这个网站的logo图片。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网