web静态服务器实现

# web静态服务器实现
web静态服务器实现,可以通过浏览器访问
##返回指定页面数据

"""返回指定页面数据"""

from socket import socket, AF_INET, SOCK_STREAM, SOL_SOCKET, SO_REUSEADDR
import re


def main():
    # 创建tcp服务端套接字
    tcp_server = socket(AF_INET, SOCK_STREAM)
    # 设置socket选项,立即释放端口,正常情况下,服务器断开连接后,需要1-2分钟才会释放端口
    tcp_server.setsockopt(SOL_SOCKET, SO_REUSEADDR, True)
    # 局域网下其他电脑可以通过 本机ip:9090访问,本机可以使用127.0.0.1:9090访问(默认是80,所以后面要加端口号)
    tcp_server.bind(("", 9090))
    # 设置监听:单任务,同一时刻只有一个客户端能建立连接,其他的都等着建立连接
    tcp_server.listen(128)
    # 循环接受可客户端的连接请求
    while True:
        # 生成一个新的套接字,专门处理这一个客户端,tcp_server就可以省下来等待其他的客户端请求
        service_client_sock, ip_port = tcp_server.accept()
        # 正常请求报文1024就足够接收了,为了防止特殊情况使用了4096
        client_request_data = service_client_sock.recv(4096)
        client_request_content = client_request_data.decode("utf-8")
        # 查找请求资源路径
        print(client_request_content)
        match_obj = re.search("r/\S*", client_request_content)
        print(match_obj)
        if not match_obj:
            print("访问路径有误")
            service_client_sock.close()
            return

        request_path = match_obj.group()
        print(request_path)
        if request_path == "/":
            request_path = "/index.html"
        # 判断访问的资源存在可以使用异常处理或者os模块的os.path.exists()
        # import os
        # os.chdir("static")
        # res = os.path.exists('index.html')
        # print(res)
        try:
            with open("static" + request_path, 'rb') as file:
                file_data = file.read()
        except Exception as e:
            # 准备响应报文数据
            # 响应行
            response_line = "HTTP/1.1 404 Not Found\r\n"
            # 响应头
            response_header = "Server: PWS1.0\r\nContent-Type: text/html;charset=utf-8\r\n"
            # 响应体 -> 打开一个404html数据把数据给浏览器
            response_body = "<h1>非常抱歉,您当前访问的网页已经不存在了</h1>".encode("utf-8")

            # 匹配响应报文数据
            response_data = (response_line + response_header + "\r\n").encode("utf-8") + response_body
            # 发送响应报文数据
            service_client_sock.send(response_data)
        else:
            # 准备响应数据
            # 响应行
            response_line = "HTTP/1.1 200 OK\r\n"
            # 响应头
            response_header = "Server: PWS1.0\r\nContent_Type: text/html; charset=utr-8\r\n"
            # 响应体
            response_body = file_data
            response_data = (response_line + response_header + "\r\n").encode("utf-8") + response_body

            service_client_sock.send(response_data)
        finally:
            service_client_sock.close()


if __name__ == "__main__":
    main()

##使用协程完成多任务web服务

"""
使用协程完成多任务web服务器,节省资源,效率比较高
gevent开辟协程如果程序一直运行则不需要加上join操作,因为程序没有退出
这程序我没有使用,from socket import socket, AF_INET, SOCK_STREAM, SOL_SOCKET, SO_REUSEADDR
因为主程序中使用socket,它识别不出来是那个socket
"""
import socket
import re
import gevent
from gevent import monkey

# 让gevent能够识别耗时操作,让协程自动切换执行,失败的耗时操作由: recv, accept, time.sleep, 网络请求延时
monkey.patch_all()


# 处理客户端的请求

def handle_client_request(service_client_socket):
    # 获取客户端的请求报文数据
    client_request_data = service_client_socket.recv(4096)
    print(client_request_data)
    # GET /index2.html HTTP/1.1xxxxxxx
    client_request_conent = client_request_data.decode("utf-8")
    # 通过正则查找请求的资源路径
    match_obj = re.search("/\S*", client_request_conent)

    if not match_obj:
        print("访问路径有误")
        service_client_socket.close()
        return

    # 获取匹配结果
    request_path = match_obj.group()
    print(request_path)

    if request_path == "/":
        # 如果用户没有指定资源路径那么默认访问的数据是首页的数据
        request_path = "/index.html"

    # 读取指定文件数据
    # 使用rb的原因是浏览器也有可能请求的是图片
    try:
        with open("static" + request_path, "rb") as file:
            # 读取文件数据
            file_data = file.read()
    except Exception as e:
        # 准备响应报文数据
        # 响应行
        response_line = "HTTP/1.1 404 Not Found\r\n"
        # 响应头
        response_header = "Server: PWS1.0\r\nContent-Type: text/html;charset=utf-8\r\n"
        # 响应体 -> 打开一个404html数据把数据给浏览器
        response_body = "<h1>非常抱歉,您当前访问的网页已经不存在了</h1>".encode("utf-8")

        # 匹配响应报文数据
        response_data = (response_line + response_header + "\r\n").encode("utf-8") + response_body
        # 发送响应报文数据
        service_client_socket.send(response_data)
    else:
        # 准备响应报文数据
        # 响应行
        response_line = "HTTP/1.1 200 OK\r\n"
        # 响应头
        response_header = "Server: PWS1.0\r\nContent-Type: text/html;charset=utf-8\r\n"
        # 响应体
        response_body = file_data

        # 匹配响应报文数据
        response_data = (response_line + response_header + "\r\n").encode("utf-8") + response_body
        # 发送响应报文数据
        service_client_socket.send(response_data)
    finally:
        service_client_socket.close()


def main():
    # 创建tcp服务端套接字
    tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 设置socket选项,立即释放端口
    tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
    # 绑定端口号
    tcp_server_socket.bind(("", 9090))
    # 设置监听
    tcp_server_socket.listen(128)
    # 循环接收客户端的连接请求
    while True:
        service_client_socket, ip_port = tcp_server_socket.accept()
        # handle_client_request(service_client_socket)
        # 开辟协程并执行对应的任务
        gevent.spawn(handle_client_request, service_client_socket)
        # 不需要加上join,主要原有是我们的进程不会退出
        # g1.join()


if __name__ == '__main__':
    main()

使用面向对象的方式实现web静态服务器

"面向对象服务器开发"

import socket
import re
import gevent
from gevent import monkey

# 让gevent能够识别耗时操作,让协程自动切换执行,失败的耗时操作由: recv, accept, time.sleep, 网络请求延时
monkey.patch_all()


class HttpWebServer(object):
    def __init__(self):
        # 创建tcp服务端套接字
        tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # 设置socket选项,立即释放端口
        tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
        # 绑定端口号
        tcp_server_socket.bind(("", 9090))
        # 设置监听
        tcp_server_socket.listen(128)
        self.tcp_server_socket = tcp_server_socket

    @staticmethod
    def handle_client_request(service_client_socket):
        # 获取客户端的请求报文数据
        client_request_data = service_client_socket.recv(4096)
        print(client_request_data)
        # GET /index2.html HTTP/1.1xxxxxxx
        client_request_conent = client_request_data.decode("utf-8")
        # 通过正则查找请求的资源路径
        match_obj = re.search("/\S*", client_request_conent)

        if not match_obj:
            print("访问路径有误")
            service_client_socket.close()
            return

        # 获取匹配结果
        request_path = match_obj.group()
        print(request_path)

        if request_path == "/":
            # 如果用户没有指定资源路径那么默认访问的数据是首页的数据
            request_path = "/index.html"

        # 读取指定文件数据
        # 使用rb的原因是浏览器也有可能请求的是图片
        try:
            with open("static" + request_path, "rb") as file:
                # 读取文件数据
                file_data = file.read()
        except Exception as e:
            # 准备响应报文数据
            # 响应行
            response_line = "HTTP/1.1 404 Not Found\r\n"
            # 响应头
            response_header = "Server: PWS1.0\r\nContent-Type: text/html;charset=utf-8\r\n"
            # 响应体 -> 打开一个404html数据把数据给浏览器
            response_body = "<h1>非常抱歉,您当前访问的网页已经不存在了</h1>".encode("utf-8")

            # 匹配响应报文数据
            response_data = (response_line + response_header + "\r\n").encode("utf-8") + response_body
            # 发送响应报文数据
            service_client_socket.send(response_data)
        else:
            # 准备响应报文数据
            # 响应行
            response_line = "HTTP/1.1 200 OK\r\n"
            # 响应头
            response_header = "Server: PWS1.0\r\nContent-Type: text/html;charset=utf-8\r\n"
            # 响应体
            response_body = file_data

            # 匹配响应报文数据
            response_data = (response_line + response_header + "\r\n").encode("utf-8") + response_body
            # 发送响应报文数据
            service_client_socket.send(response_data)
        finally:
            service_client_socket.close()

    def start(self):

        # 循环接收客户端的连接请求
        while True:
            service_client_socket, ip_port = self.tcp_server_socket.accept()
            # handle_client_request(service_client_socket)
            # 开辟协程并执行对应的任务
            gevent.spawn(self.handle_client_request, service_client_socket)
            # 不需要加上join,主要原有是我们的进程不会退出
            # g1.join()


def main():
    server = HttpWebServer()
    server.start()


if __name__ == '__main__':
    main()

通过命令行启动服务器,可以自动设置端口号

import sys
import socket
import re
import gevent
from gevent import monkey

# 让gevent能够识别耗时操作,让协程自动切换执行,失败的耗时操作由: recv, accept, time.sleep, 网络请求延时
monkey.patch_all()


class HttpWebServer(object):
    def __init__(self, port):
        # 创建tcp服务端套接字
        tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # 设置socket选项,立即释放端口
        tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
        # 绑定端口号
        tcp_server_socket.bind(("", port))
        # 设置监听
        tcp_server_socket.listen(128)
        self.tcp_server_socket = tcp_server_socket

    @staticmethod
    def handle_client_request(service_client_socket):
        # 获取客户端的请求报文数据
        client_request_data = service_client_socket.recv(4096)
        print(client_request_data)
        # GET /index2.html HTTP/1.1xxxxxxx
        client_request_conent = client_request_data.decode("utf-8")
        # 通过正则查找请求的资源路径
        match_obj = re.search("/\S*", client_request_conent)

        if not match_obj:
            print("访问路径有误")
            service_client_socket.close()
            return

        # 获取匹配结果
        request_path = match_obj.group()
        print(request_path)

        if request_path == "/":
            # 如果用户没有指定资源路径那么默认访问的数据是首页的数据
            request_path = "/index.html"

        # 读取指定文件数据
        # 使用rb的原因是浏览器也有可能请求的是图片
        try:
            with open("static" + request_path, "rb") as file:
                # 读取文件数据
                file_data = file.read()
        except Exception as e:
            # 准备响应报文数据
            # 响应行
            response_line = "HTTP/1.1 404 Not Found\r\n"
            # 响应头
            response_header = "Server: PWS1.0\r\nContent-Type: text/html;charset=utf-8\r\n"
            # 响应体 -> 打开一个404html数据把数据给浏览器
            response_body = "<h1>非常抱歉,您当前访问的网页已经不存在了</h1>".encode("utf-8")

            # 匹配响应报文数据
            response_data = (response_line + response_header + "\r\n").encode("utf-8") + response_body
            # 发送响应报文数据
            service_client_socket.send(response_data)
        else:
            # 准备响应报文数据
            # 响应行
            response_line = "HTTP/1.1 200 OK\r\n"
            # 响应头
            response_header = "Server: PWS1.0\r\nContent-Type: text/html;charset=utf-8\r\n"
            # 响应体
            response_body = file_data

            # 匹配响应报文数据
            response_data = (response_line + response_header + "\r\n").encode("utf-8") + response_body
            # 发送响应报文数据
            service_client_socket.send(response_data)
        finally:
            service_client_socket.close()

    def start(self):

        # 循环接收客户端的连接请求
        while True:
            service_client_socket, ip_port = self.tcp_server_socket.accept()
            # handle_client_request(service_client_socket)
            # 开辟协程并执行对应的任务
            gevent.spawn(self.handle_client_request, service_client_socket)
            # 不需要加上join,主要原有是我们的进程不会退出
            # g1.join()


def main():
    print(sys.argv)
    # 端口号可以自定义
    if len(sys.argv) != 2:
        print("启动命令如下: python3 command_parameter_server.py 9090")
        return
    if not sys.argv[1].isdigit():
        print("启动命令如下: python3 command_parameter_server.py 9090")
        return
    port = int(sys.argv[1])
    print(port)

    server = HttpWebServer(port)
    server.start()


if __name__ == '__main__':
    main()

最后一个程序的运行已及一个界面的截图
这里写图片描述
这里写图片描述

传送门

https://download.csdn.net/download/vivian_wanjin/10661512

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
定义: 这是一款桌面级的WEB服务器 包含一个静态的http服务器与一个js脚本引擎 可以展示静态的网页与生成简单的动态页面 适合个人在windows服务器上面简单的建立http服务 支持情况: 静态http session application(仅仅能存取文本) 服务端执行的js脚本 数据库访问(反正ODBC支持的库都支持) 自定义的com组件引用 简易说明: 1 建立站点 打开编辑 设置 输入站点名称与路径 点击添加即可建立一个站点 如: myweb c: www 注意路径要以 结尾 在站点根目录下添加filter sjs与endfilter sjs(这是两个必须的过滤器 如无需写代码放两个空文件即可) 2 静态资源与动态页面 在server sjs里的server execFileTypes定义可以配置将哪些文档类型作为动态页面 当请求静态资源时会直接返回资源 当请求一个动态页面时 请求会依次在filter sjs 请求页面 endfilter sjs 进行转发 当然也可以在filter sjs里写代码来终止转发 动态页面中如果文档类型为 sjs服务器将识别为纯的服务端执行js脚本(好比servlet什么的) 在其他类型的动态页面文档中 目前有3种类型嵌入标签可用: <%c %>标签表示嵌入一段服务端执行js脚本 如:<body><%c response responseText+ "hello js"%>< body> 将返回页面<body>hello js< body> <%i %>标签表示引用资源 如:<%i src "parts part htm"%> <% %>标签表示插值 如:<body><% "hello js"%>< body> 将返回页面<body>hello js< body> 3 com组件引用 为了让web应用有更多功能扩展 该服务器可以在脚本中引用其他com组件 这里有2种引用方法 一种方法在设置里面添加引用变量名 组件名 引用类型;来添加其他com组件的引用 组件名写成 组件工程名 组件类名 形式 就像使用CreateObject时一样 引用类型可写sing与muti 其中sing为所有请求共用一个组件实例对象 muti为每个请求引用独立的组件实例对象 另外还可以在代码里使用objectLoader loadComObject attr comNm 来添加组件引用 attr为引用变量名 comNm为组件名 注意:一个新的组件在引用前应先用regsvr32 dll注册">定义: 这是一款桌面级的WEB服务器 包含一个静态的http服务器与一个js脚本引擎 可以展示静态的网页与生成简单的动态页面 适合个人在windows服务器上面简单的建立http服务 支持情况: 静态http session application(仅仅能存取文本 [更多]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值