多线程并发--threading模块-tcp
1、threading模块完成多线程并发
2、对比多进程并发
【优势】资源消耗少
【缺点】需要注意对共享资源的操作
3、实现步骤
【1】创建套接字,绑定,监听
【2】接收客户端连接请求,创建新的线程
【3】主线程继续等待其他客户端连接,分支线程执行客户端具体请求
【4】处理完客户端请求后分支线程自然退出,关闭客户端套接字
4、基于多线程并发的HTTPServer
【1】接收浏览器http请求
【2】对请求进行一定的解析
【3】根据解析结果返回对应内容
【4】如果没有请求内容则返回404
【5】组织Response格式进行回发
5、升级功能
【1】使用多线程并发
【2】增加了具体的请求解析和404情况
【3】使用类进行代码封装
【4】增加一定的数据获取功能
6、技术点
【1】threading并发
【2】tcp socket 传输
【3】HTTP请求和响应格式
from socket import * from threading import Thread import time #存放静态页面 STATIC_DIR = "./static" ADDR = ('0.0.0.0',8000) #HTTPServer类,封装具体功能 class HTTPServer(object): def __init__(self,address): #创建套接字 self.sockfd = socket() self.sockfd.setsockopt\ (SOL_SOCKET,SO_REUSEADDR,1) self.sockfd.bind(address) self.sockfd.listen(5) #为对象增加属性变量 self.name = "HTTPServer" self.port = address[1] self.address = address #启动服务器 def serve_forever(self): print("Listen the port %d"%self.port) while True: connfd,addr = self.sockfd.accept() #创建线程处理具体请求 clientThread = Thread\ (target = self.handleRequest,args = (connfd,)) clientThread.setDaemon(True) clientThread.start() def handleRequest(self,connfd): #接收客户端请求 request = connfd.recv(4096) #按行切割 字符串 requestHeadlers = request.splitlines() #获取请求行 print(connfd.getpeername(),":",\ requestHeadlers[0]) #获取请求内容 getRequest = str(requestHeadlers[0]).split(' ')[1] if getRequest == '/' or getRequest[-5:] == '.html': data = self.get_html(getRequest) else: data = self.get_data(getRequest) connfd.send(data.encode()) connfd.close() def get_html(self,page): if page == "/": filename = STATIC_DIR + "/index.html" else: filename = STATIC_DIR + page try: f = open(filename) except Exception: #没有找到页面 responseHeadlers = "HTTP/1.1 404 Not Found\r\n" responseHeadlers += "Content-Type: text/html\r\n" responseHeadlers += '\r\n' responseBody = "<h1>Sorry,not found the page</h1>" else: responseHeadlers = "HTTP/1.1 200 OK\r\n" responseHeadlers += "Content-Type: text/html\r\n" responseHeadlers += '\r\n' responseBody = f.read() finally: return responseHeadlers + responseBody def get_data(self,data): responseHeadlers = "HTTP/1.1 200 OK\r\n" responseHeadlers += "\r\n" if data == "/time": responseBody = time.ctime() elif data == "/tttt": responseBody = "Welcome to tttt" else: responseBody = "The data not found" return responseHeadlers + responseBody if __name__ == "__main__": #生成服务器对象 httpd = HTTPServer(ADDR) #启动服务器 httpd.serve_forever()
【tcp-client.py】
from socket import * #创建套接字 sockfd = socket() #发起连接 sockfd.connect(('127.0.0.1',8888)) while True: #消息收发 msg = input("Msg>>") if not msg: break sockfd.sendall(msg.encode()) data = sockfd.recv(1024) print(data.decode()) sockfd.close()