TCP服务器非堵塞面向对象长连接

面向对象封装,相关的函数放到一个对象中,便于管理

def main():
    # server_socket = init_server()
    # run_server(server_socket)
    tcp_server = WebServer()
    tcp_server.run_server()


class WebServer(object):
    def run_server(self):
        """运行服务"""
        # 设置server_socket的非堵塞状态
        self.server_socket.setblocking(False)
        # 使用客户端列表接收新的客户端
        clients = list()
        # 循环接收客户请求
        while True:
            # 使用非堵塞时,会报错,用try进行捕获异常
            try:
                # 从三次握手的队列中取出一个客户端关联的套接字
                client, addr = self.server_socket.accept()
                # client_run(client)
                print(client)
                # 将新接收的客户端放到客户端列表中
                clients.append(client)

                # 设置客户端的非堵塞状态
                client.setblocking(False)
            except Exception as e:
                pass
            # 循环取出客户端,查看是否有数据
            for client_new in clients:
                # 捕获client的非堵塞状态时产生的异常
                try:
                    # 接收客户端发送过来的数据
                    data = client_new.recv(1024).decode()
                    # 判断是否有数据
                    if data:  # 有数据
                        # 处理一个客户端的请求
                        self.client_run(client_new, data)
                    else:  # 没有数据
                        client_new.close()  # 关闭没有数据的客户端套接字
                        clients.remove(client_new)  # 将没有数据的客户端从列表中删除
                except Exception as e:
                    pass


        # 关闭套接字
        self.server_socket.close()

    def client_run(self, client,data):
        """处理一个客户端请求"""
        # 接收数据
        # print(client)
        # time.sleep(10)
        # data = client.recv(1024).decode()
        # 将接收的数据分割为以每一行作为一个元素的列表
        header_lines = data.splitlines()
        try:
            header_line = header_lines[0]
            print(header_line)
            res = re.match(r"[^/]+([^ ]*)", header_line)
            # 判断是否匹配
            if res:  # 匹配了
                file = res.group(1)
                # 如果是"/",则是在访问首页"index.html"
                if file == "/":
                    file = "/index.html"
        except Exception as e:
            print(e)
        try:
            # 发送数据
            with open("./html%s" % file, "rb") as f:
                body = f.read()
            header = "HTTP/1.1 200 0K\r\n"
            # http头部字段告诉浏览器接收多少字节结束本次数据的传输
            # Content-Length:xxx\r\n
            header += "Content-Length:%d\r\n" % len(body)
            content = header + "\r\n"
            client.send(content.encode("utf-8"))
            client.send(body)
        except Exception as e:
            print(e)
            header = "HTTP/1.1 404 NOT FIND\r\n"
            body = "页面不见了"
            content = header + "\r\n" + body
            client.send(content.encode("utf-8"))

        # 关闭套接字
        # client.close()-----------注释掉关闭客户端,就是长连接


    def __init__(self):
        """创建tcp套接字"""
        # 创建tcp服务器端套接字
        self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # 设置套接字地址选项
        self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        # 绑定本地端口
        self.server_socket.bind(("", 9999))
        # 变为被动套接字
        self.server_socket.listen(128)
        # return server_socket


if __name__ == '__main__':
    main()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值