zoukankan      html  css  js  c++  java
  • 单线程非阻塞长链接

    轮询的方法接收数据,效率低,套接字越多,需要的时间越长

    代码:

     1 import socket
     2 import re
     3 
     4 
     5 def client_msg(new_client,recv_data):
     6     # 接收客户端请求
     7     # recv_data = new_client.recv(1024).decode("utf-8")
     8     # 把读出的数据分行
     9     recv_data_lines = recv_data.splitlines()
    10     # 正则匹配GET后面的请求的页面
    11     # [^/]表示非“/”字符 +表示至少1个或多个,[^ ]只要不是空格,*表示0个或多个
    12     ret = re.match(r"[^/]+(/[^ ]*)",recv_data_lines[0])
    13 
    14     # ret = re.search(r"/[^ ]*",recv_data_lines[0])  # 查找第一次“/”后面非空格的字符串
    15     file_name = ret.group(1)
    16     # 打开文件
    17     try:
    18         f = open("./html" + file_name,"rb")
    19     except:
    20         # 创建返回数据 HEADER
    21         response = "HTTP/1.1 404 NOT FOUND
    "
    22         response += "
    "
    23         response += "-----NOT FOUND----"
    24         # 发送数据到客户端
    25         new_client.send(response.encode("utf-8"))
    26     else:
    27         # 读出数据
    28         html_content = f.read()
    29         # 把读出的数据放到BODY体里面
    30         response_body = html_content
    31 
    32         # 创建返回数据 HEADER
    33         response_header = "HTTP/1.1 200 ok
    "
    34         # 告诉浏览器发送过去的长度
    35         response_header += "Content-Length:%d
    " % len(response_body)
    36         response_header += "
    "
    37         # 把HEADER和BODY拼接在一起
    38         response = response_header.encode("utf-8") + response_body
    39         # 发送数据到客户端
    40         new_client.send(response)
    41        
    42     # 关闭套接字 长链接不要关闭此套接字 等客户端关闭
    43     # new_client.close()
    44 
    45 
    46 def main():
    47     # 创建套接字
    48     tcp_server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    49     # 设置当服务器先调用close() 即服务器4次回收之后资源能够立即释放,这样就保证了下次运行程序时,可以立即使用
    50     # SO_REUSEADDR重复使用地址
    51     tcp_server_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
    52     # 绑定端口
    53     tcp_server_socket.bind(("",7890))
    54     # 设置监听状态
    55     tcp_server_socket.listen(128)
    56     # 设置非堵塞
    57     tcp_server_socket.setblocking(False)
    58 
    59     # 新建socket存储列表
    60     new_client_list = list()
    61 
    62     # 新建为客户端服务的套接字
    63     while True:
    64         try:
    65             new_client,client_addr = tcp_server_socket.accept()
    66         except Exception as ret:
    67            pass
    68         else:
    69             # 新套接字设置非堵塞
    70             new_client.setblocking(False)
    71             # 把新套接字放入客户端服务套接字列表
    72             new_client_list.append(new_client)
    73         # 遍历套接字列表,循环查看有没有数据过来 ----轮询
    74         for new_client_socket in new_client_list:
    75             try:
    76                 # 如果有数据,就接收并解码
    77                 recv_data = new_client_socket.recv(1024).decode("utf-8")
    78             except Exception as ret:
    79                 # 如果没数据就抛出异常 pass处理
    80                 pass
    81             else:
    82                 # 接收的如果是客户的请求数据
    83                 if recv_data:
    84                     # 调用客户端服务
    85                     client_msg(new_client_socket,recv_data)
    86                 # 如果是客户端调用close() 则关闭套接字移出列表
    87                 else:
    88                     new_client_socket.close()
    89                     # 移出列表节省资源
    90                     new_client_list.remove(new_client_socket)
    91 
    92     # 关闭套接字
    93     tcp_server_socket.close()
    94 
    95 
    96 if __name__ == '__main__':
    97     main()
  • 相关阅读:
    采用泛型链接多类型数据库[含源码]
    .NET 框架中的 Factory 模式
    .NET2.0 框架中的 AbstractFactory 模式
    Microsoft Ajax 脚本浅析
    Refactoring to Patterns 项目实践
    自动校验控件演示[含源码]
    用户定制Asp2.0 WebPart菜单
    设计模式三重天[之二]
    回DUDU关于discuzNT 模版的一些疑惑
    设计模式三重天[之一]
  • 原文地址:https://www.cnblogs.com/yifengs/p/11419473.html
Copyright © 2011-2022 走看看