专栏首页Devops专栏Python 开发web服务器,多线程

Python 开发web服务器,多线程

前面介绍了使用进程的方式来优化处理http请求

但是多进程其实也存在一个资源的问题,当一个请求过来就要开启一个子进程的话,那么如果并发来了10万的http请求,那么就可能要开启10万个子进程。 这样是非常消耗服务器资源的。

那么另一个解决的方式就是使用线程。

改写线程的方式如下

运行效果如下:

其实线程对于性能的提升在python中并不会很高,因为GIL这个全局锁的方式会对多线程进行锁定,导致性能损耗偏大 那么下一步,考虑可以使用协程gevent来优化。

完整代码

#coding=utf-8
from socket import *
import re
import threading

def handle_client(client_socket):
    """为一个客户端服务"""
    # 接收对方发送的数据
    recv_data = client_socket.recv(1024).decode("utf-8") #  1024表示本次接收的最大字节数
    # 打印从客户端发送过来的数据内容
    #print("client_recv:",recv_data)
    request_header_lines = recv_data.splitlines()
    for line in request_header_lines:
        print(line)
     
    # 返回浏览器数据
    # 设置内容body
    # 使用正则匹配出文件路径
    print("------>",request_header_lines[0])
    print("file_path---->","./html/" + re.match(r"[^/]+/([^\s]*)",request_header_lines[0]).group(1))
    ret = re.match(r"[^/]+/([^\s]*)",request_header_lines[0])
    if ret:
       file_path = "./html/" + ret.group(1)
       if file_path == "./html/":
          file_path = "./html/index.html"
       print("file_path *******",file_path)

    try:
       # 设置返回的头信息 header
       response_headers = "HTTP/1.1 200 OK\r\n" # 200 表示找到这个资源
       response_headers += "\r\n" # 空一行与body隔开
       # 读取html文件内容
       file_name = file_path # 设置读取的文件路径
       f = open(file_name,"rb") # 以二进制读取文件内容
       response_body = f.read()
       f.close()   
       # 返回数据给浏览器
       client_socket.send(response_headers.encode("utf-8"))   #转码utf-8并send数据到浏览器
       client_socket.send(response_body)   #转码utf-8并send数据到浏览器
    except:
       # 如果没有找到文件,那么就打印404 not found
       # 设置返回的头信息 header
       response_headers = "HTTP/1.1 404 not found\r\n" # 200 表示找到这个资源
       response_headers += "\r\n" # 空一行与body隔开
       response_body = "<h1>sorry,file not found</h1>"
       response = response_headers + response_body
       client_socket.send(response.encode("utf-8"))

    client_socket.close()

def main():
   # 创建套接字
   server_socket = socket(AF_INET, SOCK_STREAM)
   # 设置当服务器先close 即服务器端4次挥手之后资源能够立即释放,这样就保证了,下次运行程序时 可以立即绑定7788端口
   server_socket.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
   # 设置服务端提供服务的端口号
   server_socket.bind(('', 7788))
   # 使用socket创建的套接字默认的属性是主动的,使用listen将其改为被动,用来监听连接
   server_socket.listen(128) #最多可以监听128个连接
   # 开启while循环处理访问过来的请求 
   while True:
      # 如果有新的客户端来链接服务端,那么就产生一个新的套接字专门为这个客户端服务
      # client_socket用来为这个客户端服务
      # server_socket就可以省下来专门等待其他新的客户端连接while True:
      client_socket, clientAddr = server_socket.accept()
      # handle_client(client_socket)
      # 设置线程
      new_thread = threading.Thread(target=handle_client,args=(client_socket,))
      new_thread.start() # 开启线程


if __name__ == "__main__":
   main()

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Python 开发web服务器,多进程优化

    前面写了两个篇章,主要介绍了使用tcp开发web服务器的功能。 Python 开发Web静态服务器 - 返回固定值:胖子老板,来包槟榔 Python 开发w...

    Devops海洋的渔夫
  • Python web框架开发 - WSGI协议

    前面我利用TCP协议,返回HTTP数据的方法,实现了web静态页面返回的服务端功能。 但是这样并不能满足大部分的功能需求。

    Devops海洋的渔夫
  • Python 开发Web静态服务器 - 返回固定值:胖子老板,来包槟榔

    上一个章节讲述了关于http的基本内容。那么下面使用NetAssist来模拟http访问的以及数据返回。

    Devops海洋的渔夫
  • Python 开发web服务器,多进程优化

    前面写了两个篇章,主要介绍了使用tcp开发web服务器的功能。 Python 开发Web静态服务器 - 返回固定值:胖子老板,来包槟榔 Python 开发w...

    Devops海洋的渔夫
  • Python web框架开发 - WSGI协议

    前面我利用TCP协议,返回HTTP数据的方法,实现了web静态页面返回的服务端功能。 但是这样并不能满足大部分的功能需求。

    Devops海洋的渔夫
  • Python简单实现Web服务器

    py3study
  • Web静态服务器

    如果在发送文件的时候,有可能一次发送不完整,显示有误,可能是文件太大。我们可以将send方法改成sendall方法,即可解决

    小闫同学啊
  • Python 开发Web静态服务器 - 返回固定值:胖子老板,来包槟榔

    上一个章节讲述了关于http的基本内容。那么下面使用NetAssist来模拟http访问的以及数据返回。

    Devops海洋的渔夫
  • 面向对象封装的web服务器

    skylark
  • Response响应

    在去发送一个请求时,先会找到主机服务器再找到对应的Service,找到Servoce对应的引擎

    木瓜煲鸡脚

扫码关注云+社区

领取腾讯云代金券