Python 使用非阻塞原理实现tcp服务器多线程,并用系统epoll改进tcp服务器,实现高效并发 两份源码!

原创 2018年04月17日 12:06:41
""" 除了使用进程池,线程,协程外.   可以考虑使用非堵塞原理实现tcp服务器多线程,并用系统epoll改进tcp服务器"""

#一._tcp端服务器线程面向非堵塞

import socket
import re

import time




def main():
    # tcp_server = init_server()
    #
    # # 循环去处理客户请求
    # run_server(tcp_server)

    # server = WebServer()
    # tcp_server = server.init_server()
    # WebServer.run_server(tcp_server)

    tcp_server = WebServer()
    tcp_server.run_server()




class WebServer(object):



    def run_server(self):
        """运行服务"""
        #客户端列表
        clients = list()



        #设置服务器端非堵塞
        self.tcp_server.setblocking(False)
        while True:
            try:
                client, addr = self.tcp_server.accept()

                # print(client)
                # print(addr)  F2定位错误
                # self.client_exec(client))
                #客户端也是非堵塞
                client.setblocking(False)

                #放到我们的列表中
                clients.append(client)
            except Exception as e:
                pass


            # else:
            # print("-------错误---------")
            #循环去遍历我们的列表
            for client_new in clients:
                # print("------xxxxxx------",clients)
                try:
                    data = client_new.recv(1024).decode()
                    print(data)
                    if data:
                        #有数据
                        self.client_exec(client_new,data)
                    else:
                        print("关闭了客户端")
                        #关闭了客户端
                        client_new.close()
                        clients.remove(client_new)

                except Exception as e:
                    pass




        # 关闭服务器
        self.tcp_server.close()

    def client_exec(self, client,data):
        """这个就是单独客户端的处理"""
        # 接收数据
        # 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()

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

    # return tcp_server


if __name__ == '__main__':
    main()


#二._tcp端服务器使用_epoll实现多任务处理

import socket

import select


def main():
    tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    tcp_server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
    tcp_server.bind(("",8989))
    tcp_server.listen(128)
    #创建epoll对象
    select_epoll = select.epoll()
    #注册
    select_epoll.register(tcp_server.fileno(),select.EPOLLIN)  #tcp_server.fileno这个是文件标识符 ,epollin这个就是数据 来
    #字典
    epoll_dict= dict()

    while True:
        # client,addres = tcp_server.accept()
        epoll_list = select_epoll.poll()  #这个epoll的列表有数据过来的时候
        #列表循环的判断
        for fd,evnet in epoll_list:
            if fd == tcp_server.fileno():
                #说明服务端的数据
                client,address = tcp_server.accept()  #直接接收数据
                #客户端的数据也要注册,因为我客户也要收数据
                #注册
                select_epoll.register(client.fileno(),select.EPOLLIN)
                #把每一个客户端存起来,方便后期访问
                epoll_dict[client.fileno()] = client
            else:
                #客户端的数据
                data = epoll_dict[fd].recv(1024).decode()
                #处理用户关闭的连接
                if data:
                    print(data)
                else:
                    epoll_dict[fd].close() #关闭连接
                    select_epoll.unregister(fd) #反注册,注销,从epoll删除
                    # epoll_dict.pop(fd)  #删除字典
                    del epoll_dict[fd] #删除字典

if __name__ == '__main__':
    main()






tcp高效率并发服务器

  • 2015年06月18日 21:07
  • 2KB
  • 下载

Linux网络编程——tcp并发服务器(epoll实现)

通过epoll实现tcp并发回执服务器(客户端给服务器发啥,服务器就给客户端回啥) 代码如下: #include #include #include #include #include #...
  • lianghe_work
  • lianghe_work
  • 2015-06-18 20:26:13
  • 8571

实现TCP并发服务器之三(select函数)

前面两篇介绍用进程方式和线程方式实现并发服务,其实里面调用send,read,accept函数都会导致阻塞,而linux的select函数可以使我们在程序中同时监听多个文件描述符的读写状态。程序会停在...
  • ciaos
  • ciaos
  • 2012-07-04 08:08:07
  • 2095

QT简单TCP多线程服务器端

  • 2016年06月10日 09:40
  • 10KB
  • 下载

Linux网络编程——tcp并发服务器(poll实现)

想详细彻底地了解poll或看懂下面的代码请参考《Linux网络编程——I/O复用之poll函数》 代码: #include #include #include #include #incl...
  • lianghe_work
  • lianghe_work
  • 2015-06-17 17:13:27
  • 3268

Linux C——TCP并发服务器客户端(线程实现)

服务器程序代码: #include #include #include #include #include #include #include #include #define p...
  • Eleanor_12
  • Eleanor_12
  • 2016-11-12 22:09:07
  • 2652

【原创】TCP Socket 简单练习 --- 线程池实现并发服务器

【原创】TCP Socket 简单练习 --- 线程池实现并发服务器 服务器函数执行流程 main init_system creat_pthread_pool ...
  • u010787933
  • u010787933
  • 2014-12-25 13:59:42
  • 1105

基于Python多线程的TCP客户端/服务端应用示例

基于Python多线程的TCP客户端/服务端应用示例
  • dezhihuang
  • dezhihuang
  • 2017-05-10 11:35:35
  • 1435

Linux网络编程——tcp并发服务器(多线程)

tcp多线程并发服务器 多线程服务器是对多进程服务器的改进,由于多进程服务器在创建进程时要消耗较大的系统资源,所以用线程来取代进程,这样服务处理程序可以较快的创建。据统计,创建线程与创建进程要快 ...
  • lianghe_work
  • lianghe_work
  • 2015-06-15 15:27:04
  • 9110

Linux网络编程 - TCP Socket 简单练习:线程池实现并发服务器

服务器函数执行流程 main init_system creat_pthread_pool child_work thread_m...
  • ygl840455828ygl
  • ygl840455828ygl
  • 2016-09-05 10:36:52
  • 1904
收藏助手
不良信息举报
您举报文章:Python 使用非阻塞原理实现tcp服务器多线程,并用系统epoll改进tcp服务器,实现高效并发 两份源码!
举报原因:
原因补充:

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