服务器模型

2019-04-20  本文已影响0人  遇明不散

服务器

硬件服务器

计算机主机

软件服务器
服务器架构

服务器的组织形式
c/s 客户端服务器模型
b/s 浏览器服务器模型

服务器目标
常见服务器

服务器模型

循环服务器模型
并发服务器模型

能够同时处理多个客户端请求,每有一个客户端就创建一个进程或线程处理客户端的具体请求事件,而主进程或主线程继续接受其他客户端的连接

IO并发(IO多路复用)
多进程/多线程并发

多进程并发服务器模型

使用fork实现多进程并发
# fork_server.py
from socket import *
import sys
import signal
import os

# 主机地址与端口
HOST = '127.0.0.1'
PORT = 8888
ADDR = (HOST,PORT)

# 主进程忽略子进程的退出,子进程退出自动由系统处理
signal.signal(signal.SIGCHLD,signal.SIG_IGN)

# 客户端处理函数
def client_handler(c):
    print('服务器已连接到客户端:',c.getpeername())
    try:
        while True:
            data = c.recv(1024)
            if not data:
                break
            print('%s说:%s'%(c.getpeername(),data.decode()))
            c.send('收到客户端请求'.encode())
    except (KeyboardInterrupt,SystemError):
        sys.exit('客户端退出')
    except Exception as e:
        print('服务器内部错误信息:',e)
    c.close()
    sys.exit(0)

# 创建套接字
s = socket(AF_INET,SOCK_STREAM,0)
# 设置端口可重用
s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
# 绑定
s.bind(ADDR)
# 监听
s.listen(5)
# 主进程等待接收客户端请求
print('进程%d正在等待接受请求:'%os.getpid())
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_handler(c)
    # 如果不是子进程或者创建失败,则继续等待接受其他客户端
    else:
        c.close()
        continue
使用multiprocessing模块实现多进程并发
from socket import * 
import os,sys 
from multiprocessing import Process
import traceback 

def handler():
    print("Connect from",c.getpeername())
    while True:
        data = c.recv(1024).decode()
        if not data:
            break 
        print(data)
        c.send(b'Receive request')
    c.close()

s = socket()
s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
s.bind(('0.0.0.0',8899))
s.listen(5)
while True:
    try:
        c,addr = s.accept()
    except KeyboardInterrupt:
        s.close()
        sys.exit("服务器退出")
    except Exception:
        traceback.print_exc()
        continue 
    t = Process(target = handler)
    t.daemon = True
    t.start()

多线程并发服务器模型

对比多进程并发
实现步骤
from socket import * 
import os,sys 
from threading import *
import traceback 

def handler(c):
    print("Connect from",c.getpeername())
    while True:
        data = c.recv(1024).decode()
        if not data:
            break 
        print(data)
        c.send(b'Receive request')
    c.close()

s = socket()
s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
s.bind(('0.0.0.0',8899)) 
s.listen(5)
while True:
    try:
        c,addr = s.accept()
    except KeyboardInterrupt:
        s.close()
        sys.exit("服务器退出")
    except Exception:
        traceback.print_exc()
        continue 
    t = Thread(target = handler,args = (c,))
    t.daemon = True
    t.start()

补充

import os
# 获取目录中文件列表
os.listdir(path)  
# 判断是否为普通文件
os.path.isfile()  
# 判断是否为目录
os.path.isdir()  

import traceback
# 更详细的打印异常信息
traceback.print_exc()

集成模块socketserver

通过模块的不同类的组合完成多进程/多线程的TCP/UDP的并发

套接字请求

StreamRequestHandler 处理tcp套接字请求
DatagramRequestHandler 处理udp套接字请求

创建套接字

TCPServer 创建tcp server
UDPServer 创建udp server

创建多进程

ForkingMixIn
ForkingTCPServer <--> ForkingMinIn + TCPServer
ForkingUDPServer <--> ForkingMinIn + UDPServer

创建多线程

ThreadingMixIn
ThreadingTCPServer <--> ThreadingMinIn + TCPServer
ThreadingUDPServer <--> ThreadingMinIn + UDPServer

步骤
上一篇下一篇

猜你喜欢

热点阅读