zoukankan      html  css  js  c++  java
  • web服务-2、四种方法实现并发服务器-多线程,多进程,协程,(单进程-单线程-非堵塞)

    知识点:1、使用多线程,多进程,协程完成web并发服务器 2、单进程-单线程-非堵塞也可以实现并发服务器

    1、多进程和协程的代码在下面注释掉的部分,我把三种写在一起了

    import socket
    import re
    import threading
    import multiprocessing
    import gevent
    
    """服务器收发数据"""
    def web_server(new_socket):
    
            datas = new_socket.recv(1024).decode('utf-8')  # 接收浏览器请求的数据
            print(datas)
            data1 = datas.splitlines()
            res = re.match("[^/]+(/[^ ]*)", data1[0])  # 使用正则获取到请求头部中的的第一行中的请求地址对象
            if res:  # 判断如果请求地址有内容
                file_name = res.group(1)   # 获取正则对象中的内容
                if file_name == '/':   # 如果地址是‘/’,也就是请求地址后面没有带指的页面,即主页
                    file_name = '/index.html'
            try:
                data = open('./html'+file_name,'rb')   # 获取请求的资源在服务器中的文件
            except:
                data_body = 'HTTP 404 NOT FOUND/1.1
    '  # 服务器发送消息的头部需要换行,用
    
                data_body += '
    '   # 头部和body需要空一行
                data_body += '<h1>not found</h1>'   # 服务器没找到浏览器需要的资源,返回的html页面
                new_socket.send(data_body.encode('utf-8'))  # 发送给浏览器
            else:
                data_head = 'HTTP 200 OK/1.1
    '  # 请求成功,服务器返回200
                data_head += '
    '
                data_body = data.read()
                data.close()   # 关闭文件
                new_socket.send(data_head.encode('utf-8'))
                new_socket.send(data_body)
            new_socket.close()  # 关闭新的客户端套接字

    """主程序入口""" def main(): tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 创建套接字 tcp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 防止下一次使用该服务器端口被占用情况 tcp_socket.bind(('127.0.0.1', 7789)) # 服务器绑定地址和端口 tcp_socket.listen(128) # 监听套接字 while True: new_socket, adrees = tcp_socket.accept() # 1、多进程实现并发服务 # p = multiprocessing.Process(target=web_server, args=(new_socket,)) # p.start() # 2、协程实现并发服务 # p = gevent.spawn(web_server, new_socket) # p.start() # 3、多线程实现并发服务 t = threading.Thread(target=web_server, args=(new_socket,)) t.start() t.join() new_socket.close() tcp_socket.close() # 关闭监听套接字
    if __name__ == '__main__':
    main()
    运行效果:
    浏览器访问本地,会显示一个界面,而且可以开多个浏览器一起运行

    2、单进程-单线程-非堵塞也可以实现并发服务器

    """利用单进程-单线程-非堵塞也可以实现web并发服务(即不用多线程,多进程,协程)
       思路:1、设置套接字为非堵塞
             2、在接收客户端处:因为是非堵塞,所以要捕捉异常,当有客户端进来,新客户端的套接字也要设置非堵塞
               还需要判断接recv是否是有数据,没有数据说明客户端断开连接,关闭套接字
              
    """
    
    
    def main():
        main_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        main_socket.bind(('127.0.0.1',7785))
        main_socket.listen(128)
        main_socket.setblocking(False)
        socket_list = list()
        while True:
            time.sleep(1)
            try:
                new_socket,new_adress = main_socket.accept()
            except:
                print('没有客户端进来,请稍等.....')
            else:
                print('一个新的客户端进来了......')
                new_socket.setblocking(False)
                socket_list.append(new_socket)
            for client in socket_list:
                try:
                    recv_data = client.recv(1024).decode('utf-8')
                except:
                    print('客户端没有发送过来数据')
                else:
                    print('无异常')
                    if recv_data:
                        print('客户端发来了消息')
                        print(recv_data)
                        data1 = recv_data.splitlines()
                        res = re.match("[^/]+(/[^ ]*)", data1[0])
                        if res:
                            file_name = res.group(1)
                            print('--------------' + res.group(1))
                            if file_name == '/':
                                file_name = '/index.html'
                        try:
                            data = open('./html' + file_name, 'rb')
                        except:
                            data_body = 'HTTP 404 NOT FOUND/1.1
    '
                            data_body += '
    '
                            data_body += '<h1>not found</h1>'
                            client.send(data_body.encode('utf-8'))
                        else:
                            data_body = data.read()
                            data.close()
                            data_head = 'HTTP 200 OK/1.1
    '
                            data_head += 'Content-Length:%d
    ' % len(data_body)
                            data_head += '
    '
                            reponse = (data_head.encode('utf-8')+data_body)
                            client.send(reponse)
                    else:
                        client.close()
                        socket_list.remove(client)
        main_socket.close()
    
    
    if __name__ == '__main__':
        main()
  • 相关阅读:
    [LCA] 最近公共祖先
    [DP] D. Beautiful Array
    [模板] [拓扑序列]
    [模板] 区间筛素数
    [DP] 简单的烦恼
    [贪心] 二元组最小值最大
    [模板] 树状数组及其应用
    [Trie] 最大异或对
    [模板][二分]倍增及其应用
    ios学习记录 day31 UI 9 多视图切换 导航控制器
  • 原文地址:https://www.cnblogs.com/lz-tester/p/9415906.html
Copyright © 2011-2022 走看看