硬件服务器:主机 集群
厂商 :IBM HP 联想 浪潮
软件服务器 :编写的服务端应用程序,在硬件服务器上运行,一般依托于操作系统,给用户提供一套完整的服务
httpserver --> 处理http 请求
webserver -->网站的后端应用服务器程序
邮箱服务器 -->邮件处理
ftp 文件服务器 -->文件上传下载
功能 :网络连接 | 逻辑处理 | 数据交互 | 数据传输 | 协议的实现
结构 : c / s 客户端服务器模型
b/ s 浏览器服务器模型
服务器目标 : 处理速度更快,并发量更高,安全性更强
硬件 : 更高的配置,更好的集成分布技术,更好的优化和网络安全技术
软件 : 占用资源更少,运行更稳定,算法更优良,安全性更好,并发性更高,更容易扩展
基础服务端模型
循环模型 :循环接收客户端请求,处理请求,同一时刻只能处理一个请求,处理完毕后再处理下一个
优点 : 实现简单,占用资源少
缺点 :无法同时处理多个客户端任务
适用情况 : 处理的任务可以短时间完成,不需要建立并发,更适合UDP使用
并发模型:能够同时处理多个客户端请求
IO并发 : IO多路复用
优点 : 资源消耗少,IO处理速度快
缺点 : 不能适用CPU密集型程序
多进程/多线程并发: 为每个客户端创建单独的进程线程,执行请求
优点:每个客户端可以长期占有服务器运行程序,能够使用多核资源,可以处理IO或者CPU运算
缺点:消耗系统资源高
多进程并发模型:
使用fork()实现多进程并发
1 创建套接字,绑定,监听
2 等待接收客户端请求
3 创建新的进程处理客户端请求
4 原有进程继续等待接收新的客户端连接
5 如果客户端退出则关闭子进程
import socket,signal import os,sys s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) s.bind(('127.0.0.1',6666)) s.listen() print('%s等待客户端连接'%os.getpid()) signal.signal(signal.SIGCHLD,signal.SIG_IGN) def client_(c): print(c) try: while True: date=c.recv(1024) if not date: break print(date.decode()) c.send(date) except (KeyboardInterrupt,SyntaxError): sys.exit() except Exception as e: print(e) c.close() sys.exit(0) while True: try: c,addr = s.accept() except KeyboardInterrupt: sys.exit('服务器退出') except Exception as e: print(e) continue #为客户端创建新的进程,处理请求 pid = os.fork() if pid == 0: s.close() client_(c) #父进程或者创建失败都继续等待下一个客户端连接 else: c.close() continue
集成模块的使用
python2 SocketServer
python3 SocketServer
功能:
通过模块的不同类的组合完成多进程/多线程的TCP/UDP并发
StreamRequestHandler 处理TCP套接字请求类
DatagramRequestHandler 处理UDP套接字请求类
TCPServer 创建TCP Server
UDPServer 创建UDP Server
ForkingMixIn 创建多进程
ForkingTCPServer ---> ForkingMixIn + TCPServer
ForkingUDPServer ---> ForkingMixIn + UDPServer
ThreadingMixIn 创建多线程
ThreadingTCPServer ---> ThreadingMixIn + TCPServer
ThreadingUDPServer ---> ThreadingMixIn + UDPServer
# import socketserver # class Server(socketserver.ForkingMixIn,socketserver.TCPServer): # pass # # class Hand(socketserver.BaseRequestHandler):#继承BaseRequestHandler类,覆盖handle方法 # def handle(self): # print(self.request.getpeername()) # while True: # data = self.request.recv(1024) # if not data: # break # print(data.decode()) # self.request.send(b'1111') # if __name__ == '__main__': # host = ('127.0.0.1',6666) # # server = Server(host,Hand) # server.serve_forever()
import socketserver class Server(socketserver.ForkingMixIn,socketserver.UDPServer): pass # class Hand(socketserver.DatagramRequestHandler):#继承BaseRequestHandler类,覆盖handle方法 def handle(self): #print(self.request.getpeername()) print(self.server) print(self.request) print(self.client_address) while True: data= self.rfile.readline() if not data: break print(data.decode()) self.wfile.write(b'1111') if __name__ == '__main__': host = ('127.0.0.1',6666) server = Server(host,Hand) server.serve_forever()