在列举之前,先实现一个最基础的socket程序,用来处理用户请求。

;;; server.py

import socket
import logging

def fib(n):
    if n in (0, 1):
        return 1
    return fib(n-1) + fib(n-2)

def handle_connection(client, addr):
    while True:
        data = client.recv(1024)
        data = data.decode().strip('\r\n')
        if not data:
            continue
        logging.error(data)
        num = int(data)
        logging.info(num)
        res = fib(num)
        logging.error(res)
        client.send(str(res).encode())

def run_server(host, addr):
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server.bind((host, addr))
	while True:
        client, addr = server.accept()
        handle_connection(client, addr)

if __name__ == '__main__':
    run_server('localhost', '84579')

# 使用telnet localhost 84579, 只能接受一个telnet连接, 因为当前未断开连接

多线程

用一个线程去处理每一个请求 Thread Class

;;; server.py

import socket
import logging
from threading import Thread

def fib(n):
    if n in (0, 1):
        return 1
    return fib(n-1) + fib(n-2)

def handle_connection(client, addr):
    while True:
        data = client.recv(1024)
        data = data.decode().strip('\r\n')
        if not data:
            continue
        logging.error(data)
        num = int(data)
        logging.info(num)
        res = fib(num)
        logging.error(res)
        client.send(str(res).encode())

def run_server(host, addr):
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server.bind((host, addr))
    while True:
        client, addr = server.accept()
        Thread(target=handle_connection, args=(client, addr)).start()

if __name__ == '__main__':
    run_server('localhost', '84579')

# 现在则可以接受多个telnet连接

线程池

ThreadPoolExecutor class

;;; server.py
import socket
import logging
from threading import Thread
from concurrent.futures import ThreadPoolExecutor

pool = ThreadPoolExecutor(max_workers=5)

def fib(n):
    if n in (0, 1):
        return 1
    return fib(n-1) + fib(n-2)

def handle_connection(client, addr):
    while True:
        data = client.recv(1024)
        data = data.decode().strip('\r\n')
        if not data:
            continue
        logging.error(data)
        num = int(data)
        logging.info(num)
        future = pool.submit(fib, num)
        res = future.result()
        # res = fib(num)
        client.send(str(res).encode())

def run_server(host, addr):
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    server.bind((host, addr))
    server.listen(5)
    while True:
        client, addr = server.accept()
        Thread(target=handle_connection, args=(client, addr)).start()


if __name__ == '__main__':
    run_server('localhost', 9876)

多进程

和线程写法一样: Process class

进程池

和线程池写法一样:ProcessPoolExecutor class