多进程/线程网络并发模型
基于fork和Process的多进程网络并发模型
实现步骤:
创建监听套接字
等待接收客户端请求
客户端连接创建新的进程处理客户端请求
原进程继续等待其他客户端连接
如果客户端退出,则销毁对应的进程
1 """ 2 fork_server 基于fork搭建基础网络并发模型 3 重点代码 4 5 思路分析: 6 1. 每当有一个客户端就创建一个新的进程作为客户端处理进程 7 2. 客户端如果结束,对应进程应该销毁 8 """ 9 10 from socket import * 11 import os 12 import signal 13 14 # 创建监听套接字 15 HOST = '0.0.0.0' 16 PORT = 8888 17 ADDR = (HOST,PORT) 18 19 # 客户端服务函数 20 def handle(c): 21 while True: 22 data = c.recv(1024) 23 if not data: 24 break 25 print(data.decode()) 26 c.send(b'OK') 27 c.close() 28 29 s = socket() # tcp套接字 30 s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) 31 s.bind(ADDR) 32 s.listen(3) 33 34 # 处理僵尸进程 35 signal.signal(signal.SIGCHLD,signal.SIG_IGN) 36 37 print("Listen the port %d..."%PORT) 38 39 # 循环等待客户端连接 40 while True: 41 try: 42 c,addr = s.accept() 43 except KeyboardInterrupt: 44 os._exit(0) 45 except Exception as e: 46 print(e) 47 continue 48 49 # 创建子进程处理这个客户端 50 pid = os.fork() 51 if pid == 0: # 处理客户端请求 52 s.close() 53 handle(c) 54 os._exit(0) # handle处理完客户端请求子进程也退出 55 56 # 无论出错或者父进程都要循环回去接受请求 57 # c对于父进程没用 58 c.close()
### 基于Process的多进程网络并发 from socket import * from multiprocessing import Process import sys import signal # 创建监听套接字 HOST = '0.0.0.0' PORT = 8888 ADDR = (HOST,PORT) # 处理客户端请求 def handle(c): while True: data = c.recv(1024) if not data: break print(data.decode()) c.send(b'OK') c.close() s = socket() # tcp套接字 s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) s.bind(ADDR) s.listen(3) # 处理僵尸进程 signal.signal(signal.SIGCHLD,signal.SIG_IGN) print("Listen the port %d..."%PORT) # 循环等待客户端连接 while True: try: c,addr = s.accept() except KeyboardInterrupt: sys.exit("服务器退出") except Exception as e: print(e) continue # 创建进程处理客户端请求 p = Process(target=handle,args=(c,)) p.daemon = True p.start()
基于threading的多线程网络并发
实现步骤:
创建监听套接字
循环接收客户端连接请求
当有新的客户端连接创建线程处理客户端请求
主线程继续等待其他客户端连接
当客户端退出,则对应分支线程退出
1 """ 2 thread_server 基于线程的网络并发 3 重点代码 4 5 思路分析: 6 1. 基本与进程相同,只是换为线程处理客户端请求 7 2. 当主线程结束,同时终止所有对客户端的服务 8 """ 9 10 from socket import * 11 from threading import Thread 12 import sys 13 14 # 创建监听套接字 15 HOST = '0.0.0.0' 16 PORT = 8888 17 ADDR = (HOST,PORT) 18 19 # 处理客户端请求 20 def handle(c): 21 while True: 22 data = c.recv(1024) 23 if not data: 24 break 25 print(data.decode()) 26 c.send(b'OK') 27 c.close() 28 29 s = socket() # tcp套接字 30 s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) 31 s.bind(ADDR) 32 s.listen(3) 33 34 print("Listen the port %d..."%PORT) 35 # 循环等待客户端连接 36 while True: 37 try: 38 c,addr = s.accept() 39 except KeyboardInterrupt: 40 sys.exit("服务器退出") 41 except Exception as e: 42 print(e) 43 continue 44 45 # 创建线程处理客户端请求 46 t = Thread(target=handle,args=(c,)) 47 t.setDaemon(True) 48 t.start()
1 """ 2 tcp客户端流程 3 重点代码 4 """ 5 6 from socket import * 7 8 # 创建tcp套接字 9 sockfd = socket() # 参数默认即tcp套接字 10 11 # 连接服务端程序 12 server_addr = ("127.0.0.1",8888) # 服务端地址 13 sockfd.connect(server_addr) 14 15 while True: 16 # 消息发送接收 17 data = input("Msg>>") 18 # 如果直接回车,则跳出循环 19 if not data: 20 break 21 sockfd.send(data.encode()) # 转换字节串发送 22 data = sockfd.recv(1024) 23 print("Server:",data.decode()) 24 25 sockfd.close()