Python tcp服务器端面向函数(进程,线程,协程对比) 三份源码!

原创 2018年04月17日 11:54:44
"""tcp服务器端面向函数(进程,线程,协程对比)

结论在进程+协程服务器的效率最优秀"""


# 一.进程版

import socket
import re

import time

import multiprocessing


def main():
    tcp_server = init_server()

    # 循环去处理客户请求
    run_server(tcp_server)


def run_server(tcp_server):
    """运行服务"""
    while True:
        client, addr = tcp_server.accept()
        # print(addr)  F2定位错误
        # client_exec(client)
        #让我们的多进程去服务器我们的客户端处理
        process = multiprocessing.Process(target=client_exec, args=(client,))
        process.start()  #启动  #会复制进程前的资源,操作系统在关闭资源的时间会检查资源的引用,如果全部结束才会回收资源

        # client.fileno()这个操作系统的文件标识符
        #关闭客户端资源
        client.close()  #fd文件标识符
    # 关闭服务器
    tcp_server.close()


def client_exec(client):
    print(client)
    """这个就是单独客户端的处理"""
    # 接收数据
    data = client.recv(1024).decode()
    head_lines = data.splitlines()
    try:
        print(head_lines[0])
        # GET /index.html HTTP/1.1
        # 使用正则去获取地址
        re_match = re.match(r'[^/]+(/[^ ]*)', head_lines[0])
        # 判断是否匹配了
        if re_match:  # 匹配 了
            file_name = re_match.group(1)
            # 如果是/那么去首页
            if file_name == "/":
                file_name = "/index.html"
    except Exception as e:
        print(e)  # 工作中是记录到文件

    # 返回数据
    # 响应头
    # 空行
    # 响应体
    try:
        headers = "HTTP/1.1 200 OK\r\n"

        # 会根据不同的地址返回不的内容
        # 打开文件写读文件内容
        with open("./html%s" % file_name, 'rb') as f:  # 这样写有一个好处,如果是图片就不会有问题
            body = f.read()  # 读取文件

        # body = "show page is find!"

        # content = headers +"\r\n" +body
        content = headers + "\r\n"

        # client.send(content.encode("utf-8"))
        client.send(content.encode("utf-8"))
        client.send(body)
    except Exception as e:
        print(e)
        # 返回一个404的正常显示的页面
        head = "HTTP/1.1 404 NOT FIND\r\n"
        body = "not find page!"
        content = head + "\r\n" + body

        client.send(content.encode("utf-8"))

    # 关闭客户端
    client.close()


def init_server():  # ctrl+B进入到函数
    """ 初始化tcp服务器"""
    # 服务器tcp服务器对象
    tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 设置我们的端口地址重用
    tcp_server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    # 绑定端口号
    tcp_server.bind(("", 6789))
    # 改成被动模式
    tcp_server.listen(128)
    return tcp_server


if __name__ == '__main__':
    main()




# 二.线程版:

import socket
import re

import time

import threading


def main():
    tcp_server = init_server()

    # 循环去处理客户请求
    run_server(tcp_server)


def run_server(tcp_server):
    """运行服务"""
    while True:
        client, addr = tcp_server.accept()
        # print(addr)  F2定位错误
        # client_exec(client)
        #让我们的多进程去服务器我们的客户端处理
        # process = multiprocessing.Process(target=client_exec, args=(client,))
        # process.start()  #启动  #会复制进程前的资源,操作系统在关闭资源的时间会检查资源的引用,如果全部结束才会回收资源
        #
        # # client.fileno()这个操作系统的文件标识符
        # #关闭客户端资源
        # client.close()  #fd文件标识符

        threading_thread = threading.Thread(target=client_exec, args=(client,))
        threading_thread.start()

    # 关闭服务器
    tcp_server.close()


def client_exec(client):
    print(client)
    time.sleep(10)
    """这个就是单独客户端的处理"""
    # 接收数据
    data = client.recv(1024).decode()
    head_lines = data.splitlines()
    try:
        print(head_lines[0])
        # GET /index.html HTTP/1.1
        # 使用正则去获取地址
        re_match = re.match(r'[^/]+(/[^ ]*)', head_lines[0])
        # 判断是否匹配了
        if re_match:  # 匹配 了
            file_name = re_match.group(1)
            # 如果是/那么去首页
            if file_name == "/":
                file_name = "/index.html"
    except Exception as e:
        print(e)  # 工作中是记录到文件

    # 返回数据
    # 响应头
    # 空行
    # 响应体
    try:
        headers = "HTTP/1.1 200 OK\r\n"

        # 会根据不同的地址返回不的内容
        # 打开文件写读文件内容
        with open("./html%s" % file_name, 'rb') as f:  # 这样写有一个好处,如果是图片就不会有问题
            body = f.read()  # 读取文件

        # body = "show page is find!"

        # content = headers +"\r\n" +body
        content = headers + "\r\n"

        # client.send(content.encode("utf-8"))
        client.send(content.encode("utf-8"))
        client.send(body)
    except Exception as e:
        print(e)
        # 返回一个404的正常显示的页面
        head = "HTTP/1.1 404 NOT FIND\r\n"
        body = "not find page!"
        content = head + "\r\n" + body

        client.send(content.encode("utf-8"))

    # 关闭客户端
    client.close()


def init_server():  # ctrl+B进入到函数
    """ 初始化tcp服务器"""
    # 服务器tcp服务器对象
    tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 设置我们的端口地址重用
    tcp_server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    # 绑定端口号
    tcp_server.bind(("", 6789))
    # 改成被动模式
    tcp_server.listen(128)
    return tcp_server


if __name__ == '__main__':
    main()



#三.协程版:

import socket
import re

import time

import gevent

from gevent import monkey
#让我们的系统把所有的耗时操作转换成gevent的
monkey.patch_all()


def main():
    tcp_server = init_server()

    # 循环去处理客户请求
    run_server(tcp_server)


def run_server(tcp_server):
    """运行服务"""
    while True:
        client, addr = tcp_server.accept()
        # print(addr)  F2定位错误
        # client_exec(client)
        #让我们的多进程去服务器我们的客户端处理

        gevent_spawn = gevent.spawn(client_exec, client)
        # gevent_spawn.join()

    # 关闭服务器
    tcp_server.close()


def client_exec(client):
    print(client)
    """这个就是单独客户端的处理"""
    # 接收数据
    data = client.recv(1024).decode()
    head_lines = data.splitlines()
    try:
        print(head_lines[0])
        # GET /index.html HTTP/1.1
        # 使用正则去获取地址
        re_match = re.match(r'[^/]+(/[^ ]*)', head_lines[0])
        # 判断是否匹配了
        if re_match:  # 匹配 了
            file_name = re_match.group(1)
            # 如果是/那么去首页
            if file_name == "/":
                file_name = "/index.html"
    except Exception as e:
        print(e)  # 工作中是记录到文件

    # 返回数据
    # 响应头
    # 空行
    # 响应体
    try:
        headers = "HTTP/1.1 200 OK\r\n"

        # 会根据不同的地址返回不的内容
        # 打开文件写读文件内容
        with open("./html%s" % file_name, 'rb') as f:  # 这样写有一个好处,如果是图片就不会有问题
            body = f.read()  # 读取文件

        # body = "show page is find!"

        # content = headers +"\r\n" +body
        content = headers + "\r\n"

        # client.send(content.encode("utf-8"))
        client.send(content.encode("utf-8"))
        client.send(body)
    except Exception as e:
        print(e)
        # 返回一个404的正常显示的页面
        head = "HTTP/1.1 404 NOT FIND\r\n"
        body = "not find page!"
        content = head + "\r\n" + body

        client.send(content.encode("utf-8"))

    # 关闭客户端
    client.close()


def init_server():  # ctrl+B进入到函数
    """ 初始化tcp服务器"""
    # 服务器tcp服务器对象
    tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 设置我们的端口地址重用
    tcp_server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    # 绑定端口号
    tcp_server.bind(("", 6789))
    # 改成被动模式
    tcp_server.listen(128)
    return tcp_server


if __name__ == '__main__':
    main()






python︱Python进程、线程、协程详解、运行性能、效率(tqdm)

多进程实践——multiprocessing 笔者最近在实践多进程发现multiprocessing,真心很好用,不仅加速了运算,同时可以GPU调用,而且互相之间无关联,这样可以很放心的进行计算。 ...
  • sinat_26917383
  • sinat_26917383
  • 2017-04-02 12:58:55
  • 1338

python(十)线程与进程(中):进程、协程

一、上节回顾:线程 vs 进程1、线程:一组指令 内存共享 同时修改同一份数据时必须加锁,metex 互斥锁 递归锁 join 等待线程结束 启动一个线程: def run(): prin...
  • fgf00
  • fgf00
  • 2016-10-11 18:03:37
  • 3025

进程、线程和协程的区别是什么

每天都去接触一些新的问题,生活就会少一些问题,来吧,让我们在技术的路上一探到底吧 进程拥有自己独立的堆和栈,既不共享堆,亦不共享栈,进程由操作系统调度。 线程拥有自己独立的栈和共享的堆,共享堆...
  • liu_zhuang_love
  • liu_zhuang_love
  • 2016-06-12 21:29:58
  • 1607

【Python】进程线程协程对比

简单总结 进程是资源分配的单位线程是操作系统调度的单位进程切换需要的资源很最大,效率很低线程切换需要的资源一般,效率一般协程切换任务资源很小,效率高多进程、多线程根据cpu核数不一样可能是并行的...
  • milankunde
  • milankunde
  • 2017-12-25 20:45:57
  • 108

python协程面试题(一)

题目 使用协程的概念,达到以下目的, 输入a,b,c,d四个整数,打印(a+b)*(c+d)的值。假设a+b的过程是耗时1秒IO操作。 笔者的解答 """ 使用协程的概念,达到以下目的, 输入a...
  • leon_wzm
  • leon_wzm
  • 2018-01-17 14:51:19
  • 84

进程、线程、轻量级进程、协程和go中的Goroutine 那些事儿

一、进程 操作系统中最核心的概念是进程,分布式系统中最重要的问题是进程间通信。 进程是“程序执行的一个实例” ,担当分配系统资源的实体。进程创建必须分配一个完整的独立地址空间。 ...
  • kai8wei
  • kai8wei
  • 2017-08-24 21:45:10
  • 360

线程、进程和协程

从一定意义上讲,进程就是一个应用程序在处理机上的一次执行过程,它是一个动态的概念,而线程是进程中的一部分,进程包含多个线程在运行。进程,是并发执行的程序在执行过程中分配和管理资源的基本单位,是一个动态...
  • qq_17612199
  • qq_17612199
  • 2016-03-31 17:07:00
  • 1564

进程、线程和协程的理解

进程、线程和协程的理解 进程、线程和协程之间的关系和区别也困扰我一阵子了,最近有一些心得,写一下。 进程拥有自己独立的堆和栈,既不共享堆,亦不共享栈,进程由操作系统调度。 线程拥有自...
  • hairetz
  • hairetz
  • 2013-11-14 17:13:19
  • 41806

进程、线程与协程的比较

进程、线程和协程是三个在多任务处理中常听到的概念,三者各有区别又相互联系。 进程 进程是一个程序在一个数据集中的一次动态执行过程,可以简单理解为“正在执行的程序”,它是CPU资源分配和调度的独...
  • Blateyang
  • Blateyang
  • 2017-09-25 19:59:57
  • 1860

进程/线程/协程/管程/纤程 笔记

各种程的理解
  • enlangs
  • enlangs
  • 2017-05-08 12:54:02
  • 510
收藏助手
不良信息举报
您举报文章:Python tcp服务器端面向函数(进程,线程,协程对比) 三份源码!
举报原因:
原因补充:

(最多只允许输入30个字)