Python miniWeb服务器实现

易小灯塔
2017-08-12 / 0 评论 / 1,647 阅读 / 正在检测是否收录...
温馨提示:
本文最后更新于2022年06月22日,已超过888天没有更新,若内容或图片失效,请留言反馈。

 

返回固定数据

示例代码:

import socket


def serviceClient(clientSocket):
    """为客户端服务"""
    # 1. 接收客户端发送过来的http的请求数据
    request =  clientSocket.recv(1024).decode("utf-8")
    print(">"*40, "\n", request)

    # 2. 返回http的应答数据
    responseHeader  = "HTTP/1.1 200 OK\r\n"
    responseHeader += "\r\n"
    responseBody = "are u ok?"
    response = responseHeader + responseBody

    clientSocket.send(response.encode("utf-8"))

    # 3. 关闭套接字
    clientSocket.close()


def main():
    # 1. 创建套接字
    tcpSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    # 套接字端口复用
    tcpSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    # 2. 绑定本地信息
    port = 8888
    tcpSocket.bind(("", port))
    print("服务器绑定端口为:", port)

    # 3. 设置为监听套接字
    tcpSocket.listen(128)

    while True:
        # 4. 等待新的客户端链接
        clientSocket, clientAddr = tcpSocket.accept()
        print(clientAddr, "连接成功")

        # 5. 为这个客户端服务
        serviceClient(clientSocket)

    # 6. 关闭套接字
    tcpSocket.close()

if __name__ == "__main__":
    main() 

返回固定页面

示例代码:

import socket


def serviceClient(clientSocket):
    """为客户端服务"""
    # 1. 接收客户端发送过来的http的请求数据
    request =  clientSocket.recv(1024).decode("utf-8")
    print(">"*40, "\n", request)

    # 2. 返回http的应答数据
    responseHeader  = "HTTP/1.1 200 OK\r\n"
    responseHeader += "\r\n"

    # 读取固定页面数据
    with open('./html/index.html', 'rb') as file:
        responeBody = file.read()

    clientSocket.send(responseHeader.encode("utf-8")) #先发头
    clientSocket.send(responeBody) #先发body

    # 3. 关闭套接字
    clientSocket.close()


def main():
    # 1. 创建套接字
    tcpSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    # 套接字端口复用
    tcpSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    # 2. 绑定本地信息
    port = 8888
    tcpSocket.bind(("", port))
    print("服务器绑定端口为:", port)

    # 3. 设置为监听套接字
    tcpSocket.listen(128)

    while True:
        # 4. 等待新的客户端链接
        clientSocket, clientAddr = tcpSocket.accept()
        print(clientAddr, "连接成功")

        # 5. 为这个客户端服务
        serviceClient(clientSocket)

    # 6. 关闭套接字
    tcpSocket.close()

if __name__ == "__main__":
    main() 

 

 

解析用户的请求

示例代码:

import socket
import re


def serviceClient(clientSocket):
    """为客户端服务"""
    # 1. 接收客户端发送过来的http的请求数据
    request =  clientSocket.recv(1024).decode("utf-8")
    print(">"*40, "\n", request)

    # 以行为单位切割,并返回一个列表
    requestLines = request.splitlines()
    print("====>", requestLines)

    # GET /index.html HTTP/1.1
    requestFirstLine = requestLines[0]

     # 通过正则表达式提取相应的文件名
    fileName = re.match(r"[^/]+(/[^ ]*)", requestFirstLine).group(1)
    print("-----请求的文件名是:%s" % fileName)


    # 3. 根据文件名去读取这个文件的内容,如果有就发送,如果没有就告诉浏览器 这个资源不存在404
    try:
        with open("./html" + fileName, "rb") as f:
            content = f.read()
    except Exception as ret:
        # 意味着没有这个请求的资源  404
        # 返回http的应答数据
        responseHeader  = "HTTP/1.1 404 NOT FOUND\r\n"
        responseHeader += "\r\n"
        responseBody = "------file not found-------".encode("utf-8")
    else:
        # 意味着 有这个对应的资源 200
        # 返回http的应答数据
        responseHeader  = "HTTP/1.1 200 OK\r\n"
        responseHeader += "\r\n"
        responseBody = content


    # 返回http的应答数据
    clientSocket.send(responseHeader.encode("utf-8")) #先发头
    clientSocket.send(responseBody) #先发body

    # 4. 关闭套接字
    clientSocket.close()


def main():
    # 1. 创建套接字
    tcpSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    # 套接字端口复用
    tcpSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    # 2. 绑定本地信息
    port = 8888
    tcpSocket.bind(("", port))
    print("服务器绑定端口为:", port)

    # 3. 设置为监听套接字
    tcpSocket.listen(128)

    while True:
        # 4. 等待新的客户端链接
        clientSocket, clientAddr = tcpSocket.accept()
        print(clientAddr, "连接成功")

        # 5. 为这个客户端服务
        serviceClient(clientSocket)

    # 6. 关闭套接字
    tcpSocket.close()

if __name__ == "__main__":
    main() 

解析用户的请求

示例代码:

import socket
import re


def serviceClient(clientSocket):
    """为客户端服务"""
    # 1. 接收客户端发送过来的http的请求数据
    request =  clientSocket.recv(1024).decode("utf-8")
    print(">"*40, "\n", request)

    # 以行为单位切割,并返回一个列表
    requestLines = request.splitlines()
    print("====>", requestLines)

    # GET /index.html HTTP/1.1
    requestFirstLine = requestLines[0]

     # 通过正则表达式提取相应的文件名
    fileName = re.match(r"[^/]+(/[^ ]*)", requestFirstLine).group(1)
    print("-----请求的文件名是:%s" % fileName)


    # 3. 根据文件名去读取这个文件的内容,如果有就发送,如果没有就告诉浏览器 这个资源不存在404
    try:
        with open("./html" + fileName, "rb") as f:
            content = f.read()
    except Exception as ret:
        # 意味着没有这个请求的资源  404
        # 返回http的应答数据
        responseHeader  = "HTTP/1.1 404 NOT FOUND\r\n"
        responseHeader += "\r\n"
        responseBody = "------file not found-------".encode("utf-8")
    else:
        # 意味着 有这个对应的资源 200
        # 返回http的应答数据
        responseHeader  = "HTTP/1.1 200 OK\r\n"
        responseHeader += "\r\n"
        responseBody = content


    # 返回http的应答数据
    clientSocket.send(responseHeader.encode("utf-8")) #先发头
    clientSocket.send(responseBody) #先发body

    # 4. 关闭套接字
    clientSocket.close()


def main():
    # 1. 创建套接字
    tcpSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    # 套接字端口复用
    tcpSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    # 2. 绑定本地信息
    port = 8888
    tcpSocket.bind(("", port))
    print("服务器绑定端口为:", port)

    # 3. 设置为监听套接字
    tcpSocket.listen(128)

    while True:
        # 4. 等待新的客户端链接
        clientSocket, clientAddr = tcpSocket.accept()
        print(clientAddr, "连接成功")

        # 5. 为这个客户端服务
        serviceClient(clientSocket)

    # 6. 关闭套接字
    tcpSocket.close()

if __name__ == "__main__":
    main() 

支持默认index页面

示例代码:

import socket
import re


def serviceClient(clientSocket):
    """为客户端服务"""
    # 1. 接收客户端发送过来的http的请求数据
    request =  clientSocket.recv(1024).decode("utf-8")
    print(">"*40, "\n", request)

    # 以行为单位切割,并返回一个列表
    requestLines = request.splitlines()
    print("====>", requestLines)

    # GET /index.html HTTP/1.1
    requestFirstLine = requestLines[0]

    # 通过正则表达式提取相应的文件名
    fileName = re.match(r"[^/]+(/[^ ]*)", requestFirstLine).group(1)

    # 如果后面没有路径,默认是index.html
    if fileName == "/":
        fileName = "/index.html"

    print("-----请求的文件名是:%s" % fileName)


    # 3. 根据文件名去读取这个文件的内容,如果有就发送,如果没有就告诉浏览器 这个资源不存在404
    try:
        with open("./html" + fileName, "rb") as f:
            content = f.read()
    except Exception as ret:
        # 意味着没有这个请求的资源  404
        # 返回http的应答数据
        responseHeader  = "HTTP/1.1 404 NOT FOUND\r\n"
        responseHeader += "\r\n"
        responseBody = "------file not found-------".encode("utf-8")
    else:
        # 意味着 有这个对应的资源 200
        # 返回http的应答数据
        responseHeader  = "HTTP/1.1 200 OK\r\n"
        responseHeader += "\r\n"
        responseBody = content


    # 返回http的应答数据
    clientSocket.send(responseHeader.encode("utf-8")) #先发头
    clientSocket.send(responseBody) #先发body

    # 4. 关闭套接字
    clientSocket.close()


def main():
    # 1. 创建套接字
    tcpSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    # 套接字端口复用
    tcpSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    # 2. 绑定本地信息
    port = 8888
    tcpSocket.bind(("", port))
    print("服务器绑定端口为:", port)

    # 3. 设置为监听套接字
    tcpSocket.listen(128)

    while True:
        # 4. 等待新的客户端链接
        clientSocket, clientAddr = tcpSocket.accept()
        print(clientAddr, "连接成功")

        # 5. 为这个客户端服务
        serviceClient(clientSocket)

    # 6. 关闭套接字
    tcpSocket.close()

if __name__ == "__main__":
    main() 

多任务协程版

示例代码:

import socket
import re
import gevent

from gevent import monkey
monkey.patch_all()


def serviceClient(clientSocket):
    """为客户端服务"""
    # 1. 接收客户端发送过来的http的请求数据
    request =  clientSocket.recv(1024).decode("utf-8")
    print(">"*40, "\n", request)

    # 以行为单位切割,并返回一个列表
    requestLines = request.splitlines()
    print("====>", requestLines)

    # GET /index.html HTTP/1.1
    requestFirstLine = requestLines[0]

    # 通过正则表达式提取相应的文件名
    fileName = re.match(r"[^/]+(/[^ ]*)", requestFirstLine).group(1)

    # 如果后面没有路径,默认是index.html
    if fileName == "/":
        fileName = "/index.html"

    print("-----请求的文件名是:%s" % fileName)


    # 3. 根据文件名去读取这个文件的内容,如果有就发送,如果没有就告诉浏览器 这个资源不存在404
    try:
        with open("./html" + fileName, "rb") as f:
            content = f.read()
    except Exception as ret:
        # 意味着没有这个请求的资源  404
        # 返回http的应答数据
        responseHeader  = "HTTP/1.1 404 NOT FOUND\r\n"
        responseHeader += "\r\n"
        responseBody = "------file not found-------".encode("utf-8")
    else:
        # 意味着 有这个对应的资源 200
        # 返回http的应答数据
        responseHeader  = "HTTP/1.1 200 OK\r\n"
        responseHeader += "\r\n"
        responseBody = content


    # 返回http的应答数据
    clientSocket.send(responseHeader.encode("utf-8")) #先发头
    clientSocket.send(responseBody) #先发body

    # 4. 关闭套接字
    clientSocket.close()


def main():
    # 1. 创建套接字
    tcpSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    # 套接字端口复用
    tcpSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    # 2. 绑定本地信息
    port = 8888
    tcpSocket.bind(("", port))
    print("服务器绑定端口为:", port)

    # 3. 设置为监听套接字
    tcpSocket.listen(128)

    while True:
        # 4. 等待新的客户端链接
        clientSocket, clientAddr = tcpSocket.accept()
        print(clientAddr, "连接成功")

        # 5. 为这个客户端服务
        # 创建这个对象之后,gevent就知道了当遇到耗费时间的时候可以切换到这个对象指定的函数中运行
        gevent.spawn(serviceClient, clientSocket) 

    # 6. 关闭套接字
    tcpSocket.close()

if __name__ == "__main__":
    main() 

面向对象版

示例代码:

import socket
import re
import gevent

from gevent import monkey
monkey.patch_all()

class WebServer(object):
    def __init__(self, port):
        # 1. 创建套接字
        self.tcpSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        # 套接字端口复用
        self.tcpSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

        # 2. 绑定本地信息
        self.port = port
        self.tcpSocket.bind(("", self.port))
        print("服务器绑定端口为:", self.port)

        # 3. 设置为监听套接字
        self.tcpSocket.listen(128)


    def StartUp(self):
        while True:
            # 4. 等待新的客户端链接
            clientSocket, clientAddr = self.tcpSocket.accept()
            print(clientAddr, "连接成功")

            # 5. 为这个客户端服务
            # 创建这个对象之后,gevent就知道了当遇到耗费时间的时候可以切换到这个对象指定的函数中运行
            gevent.spawn(self.serviceClient, clientSocket) 

        # 6. 关闭套接字
        self.tcpSocket.close()


    def serviceClient(self, clientSocket):
        """为客户端服务"""
        # 1. 接收客户端发送过来的http的请求数据
        request =  clientSocket.recv(1024).decode("utf-8")
        print(">"*40, "\n", request)

        # 以行为单位切割,并返回一个列表
        requestLines = request.splitlines()
        print("====>", requestLines)

        # GET /index.html HTTP/1.1
        requestFirstLine = requestLines[0]

        # 通过正则表达式提取相应的文件名
        fileName = re.match(r"[^/]+(/[^ ]*)", requestFirstLine).group(1)

        # 如果后面没有路径,默认是index.html
        if fileName == "/":
            fileName = "/index.html"

        print("-----请求的文件名是:%s" % fileName)


        # 3. 根据文件名去读取这个文件的内容,如果有就发送,如果没有就告诉浏览器 这个资源不存在404
        try:
            with open("./html" + fileName, "rb") as f:
                content = f.read()
        except Exception as ret:
            # 意味着没有这个请求的资源  404
            # 返回http的应答数据
            responseHeader  = "HTTP/1.1 404 NOT FOUND\r\n"
            responseHeader += "\r\n"
            responseBody = "------file not found-------".encode("utf-8")
        else:
            # 意味着 有这个对应的资源 200
            # 返回http的应答数据
            responseHeader  = "HTTP/1.1 200 OK\r\n"
            responseHeader += "\r\n"
            responseBody = content


        # 返回http的应答数据
        clientSocket.send(responseHeader.encode("utf-8")) #先发头
        clientSocket.send(responseBody) #先发body

        # 4. 关闭套接字
        clientSocket.close()


def main():
   # 创建服务器
    server = WebServer(8888)

    # 启动服务器
    server.StartUp()


if __name__ == "__main__":
    main() 

 

命令行参数版

示例代码:

import socket
import re
import gevent
import sys

from gevent import monkey
monkey.patch_all()

class WebServer(object):
    def __init__(self, port):
        # 1. 创建套接字
        self.tcpSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        # 套接字端口复用
        self.tcpSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

        # 2. 绑定本地信息
        self.port = port
        self.tcpSocket.bind(("", self.port))
        print("服务器绑定端口为:", self.port)

        # 3. 设置为监听套接字
        self.tcpSocket.listen(128)


    def StartUp(self):
        while True:
            # 4. 等待新的客户端链接
            clientSocket, clientAddr = self.tcpSocket.accept()
            print(clientAddr, "连接成功")

            # 5. 为这个客户端服务
            # 创建这个对象之后,gevent就知道了当遇到耗费时间的时候可以切换到这个对象指定的函数中运行
            gevent.spawn(self.serviceClient, clientSocket) 

        # 6. 关闭套接字
        self.tcpSocket.close()


    def serviceClient(self, clientSocket):
        """为客户端服务"""
        # 1. 接收客户端发送过来的http的请求数据
        request =  clientSocket.recv(1024).decode("utf-8")
        print(">"*40, "\n", request)

        # 以行为单位切割,并返回一个列表
        requestLines = request.splitlines()
        print("====>", requestLines)

        # GET /index.html HTTP/1.1
        requestFirstLine = requestLines[0]

        # 通过正则表达式提取相应的文件名
        fileName = re.match(r"[^/]+(/[^ ]*)", requestFirstLine).group(1)

        # 如果后面没有路径,默认是index.html
        if fileName == "/":
            fileName = "/index.html"

        print("-----请求的文件名是:%s" % fileName)


        # 3. 根据文件名去读取这个文件的内容,如果有就发送,如果没有就告诉浏览器 这个资源不存在404
        try:
            with open("./html" + fileName, "rb") as f:
                content = f.read()
        except Exception as ret:
            # 意味着没有这个请求的资源  404
            # 返回http的应答数据
            responseHeader  = "HTTP/1.1 404 NOT FOUND\r\n"
            responseHeader += "\r\n"
            responseBody = "------file not found-------".encode("utf-8")
        else:
            # 意味着 有这个对应的资源 200
            # 返回http的应答数据
            responseHeader  = "HTTP/1.1 200 OK\r\n"
            responseHeader += "\r\n"
            responseBody = content


        # 返回http的应答数据
        clientSocket.send(responseHeader.encode("utf-8")) #先发头
        clientSocket.send(responseBody) #先发body

        # 4. 关闭套接字
        clientSocket.close()


def main():
    if len(sys.argv) < 2:
        print('您需要指定监听端口!')
        return

    # 获取用户指定的绑定端口
    port = int(sys.argv[1])

    # 创建服务器
    server = WebServer(port)

    # 启动服务器
    server.StartUp()


if __name__ == "__main__":
    main() 
0

评论 (0)

取消