Threading 的多线程并发

  • threading 的多线程并发

threading 的多线程并发 对 比多进程并发:
    *消耗资源较少
    *线程应该更注意共享资源的操作
    *在Pythonh中应该注意GIT问题,网络延迟较高,线程并发也是一种可行的操作

实现步骤:
    1.创建套接字
    2.接受客户端请求,创建新的线程
    3.主程序继续接受其他客户端连接
    4.分支线程启动对应的函数处理客户端请求
    5.当客户端断开,则分支线程结束

# socket_server.py
from socketserver import *


# 创建服务器类
class Server(ForkingMixIn,TCPServer):
    pass


class Handler(StreamRequestHandler):
    def handle(self):
        # self.request ==> accept 返回的套接字
        print('Connect from', self.request.getpeername())
        while True:
            data = self.request.recv(1024)
            if not data:
                break
            print(data.decode())
            self.request.send(b'Recive')


if __name__=="__main__":
    server_addr = ('0.0.0.0', 9999)

    # 创建服务器对象
    server = Server(server_addr, Handler)
    # 启动服务器
    server.serve_forever()

cookie

    import traceback
    功能:更详细的打印异常信息

    traceback.print_exc()
    功能:更详细的打印异常信息


集成模块的使用

    python2 SocketServer

    python3 socketserver

功能:通过模块的不同 类的组合完成多进程,多线程的tcp/udp的并发
 
    StreamRequestHandler  处理tcp套接字请求
    DatagramRequestHandler  处理udp套接字请求


    TCPServer 创建tcp server
    UDPServer 创建ucp server


    ForkingMixIn   创建多进程
    ForkingTCPServer -->ForkingMixIn + TCPServer
    ForkingUDPServer -->ForkingMixIn + UDPServer


    ThreadingMixIn 创建多线程
    ThreadingTCPServer -->ThreadingMixIn + TCPServer
    ThreadingUDPServer -->ThreadingMixIn + UDPServer

 

HTTPServer v2.0

1.接收客户端请求
2.解析客户端请求
3.组织数据形成HTTP reponse
4.将数据发给客户端


升级
1.采用多线程并发接收多个客户端请求
2.基本的请求解析,根据请求返回相应的内容
3.除了可以请求静态网页,也可以请求简单的数据
4.将功能封装在一个类中

技术点:
1.socket  tcp 套接字
2.http协议的请求相应格式
3.线程并发的创建方法
4.类的基本使用

#!usr/bin/env python3
# coding=utf-8

'''
1.多线程并发
2.可以请求简单数据
3.能进行简单请求分析
4.结构使用类进行封装
'''

from socket import *
from threading import Thread
import sys
import traceback


# HTTPserver类,封装具体的服务器功能
class HttpServer(object):
    def __init__(self, server_addr, static_dir):
        # 增添服务器对象属性
        self.server_address = server_addr
        self.static_dir = static_dir  # 我的静态页面存储目录
        self.ip = server_addr[0]     # 地址
        self.port = server_addr[1]   # 端口
        # 创建套接字
        self.create_socket()

    def create_socket(self):
        self.sockfd = socket()
        self.sockfd.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)  # 释放端口
        self.sockfd.bind(self.server_address)  # 连接

    def serve_forever(self):
        self.sockfd.listen(5)
        print('Listen the port %d' % self.port)
        while True:
            try:
                connfd, addr = self.sockfd.accept()
            except KeyboardInterrupt:
                self.sockfd.close()
                sys.exit('服务器退出')
            except Exception:
                traceback.print_exc()
                continue

            # 创建新的线程处理请求
            clientThread = Thread(target=self.handleRequest,
                                  args=(connfd,))
            clientThread.setDaemon(True)
            clientThread.start()

    # 客户端请求函数
    def handleRequest(self, connfd):
        # 接收客户端请求
        request = connfd.recv(4096)
        # 解析请求内容
        requestHeaders = request.splitlines()
        print(connfd.getpeername(), ":", requestHeaders[0])

        # 获取具体请求内容
        getRequest = str(requestHeaders[0]).split(' ')[1]

        if getRequest == '/' or getRequest[-5:] == './html':
            self.get_html(connfd, getRequest)
        else:
            self.get_data(connfd, getRequest)
        connfd.close()

    def get_html(self, connfd, getRequest):
        if getRequest == '/':
            filename = self.static_dir + '/index.html'
        else:
            filename = self.static_dir + getRequest
        try:
            f = open(filename)
        except Exception:
            # 没有找到网页
            responseHeaders = 'HTTP/1.1 404 NOT FOUND\r\n'
            responseHeaders += '\r\n'
            responseBody = 'sorry,not found the page'
        else:
            responseHeaders = 'HTTP/1.1 200 OK\r\n'
            responseHeaders += '\r\n'
            responseBody = f.read()
        finally:
            response = responseHeaders + responseBody
            connfd.send(response.encode())

    def get_data(self, connfd, getRequest):
        urls = ['/time', '/tedu', '/python']

        if getRequest in urls:
            responseHeaders = 'HTTP/1.1 200 OK\r\n'
            responseHeaders += '\r\n'
            if getRequest == '/time':
                import time
                responseBody = time.ctime()

            elif getRequest == '/tedu':
                responseBody = 'welcome to tarena'

            elif getRequest == '/python':
                responseBody = '人生苦短我用Python'

        else:
            responseHeaders = 'HTTP/1.1 404 NOT FOUND\r\n'
            responseHeaders += '\r\n'
            responseBody = 'sorry,not found the page'
        response = responseHeaders + responseBody
        connfd.send(response.encode())


if __name__ == "__main__":
    # 服务器IP
    server_addr = ('0.0.0.0', 8888)
    # 我的静态页面存储目录
    static_dir = './static'

    # 生成对象
    httpd = HttpServer(server_addr, static_dir)
    # 启动服务器
    httpd.serve_forever()

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值