• 基于线程池的多并发Socket程序的实现


      Socket“服务器-客户端”模型的多线程并发实现效果的大体思路是:首先,在Server端建立“链接循环”,每一个链接都开启一个“线程”,使得每一个Client端都能通过已经建立好的线程来同时与Server通信,代码如下:

    # -*- coding: utf-8  -*-
    # -*- Author: WangHW -*-
    import socket
    from threading import Thread
    
    
    def Communication(conn):
        # 通信循环
        while 1:
            try:
                data = conn.recv(1024)
                if not data:
                    break
                print('Client Data:', data.decode('utf-8'))
                conn.send(data.upper())
            except ConnectionResetError:
                break
    
    def Server(ip,post):
        whw_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        whw_server.bind((ip,post))
        whw_server.listen(5)
        # 链接循环
        while 1:
            conn, addr = whw_server.accept()
            #创建线程
            t = Thread(target=Communication,args=(conn,))
            t.start()
    
    if __name__ == '__main__':
        #主线程干Server的工作
        Server('127.0.0.1',9000)
    Server
    # -*- coding: utf-8  -*-
    # -*- Author: WangHW -*-
    import socket
    
    whw_client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    whw_client.connect(('127.0.0.1',9000))
    
    while 1:
        msg = input('>>>:').strip()
        if not msg:
            continue
        whw_client.send(msg.encode('utf-8'))
        data = whw_client.recv(1024)
        print('Server Data:',data.decode('utf-8'))
    Client

      运行效果如下:

      但是,这样的设计存在一个十分严重的问题:由于Server端存在性能问题,因此它不能无限的去开启线程,也就是说服务的开启的进程数或线程数都会随着并发的客户端数目地增多而增多,这会对服务端主机带来巨大的压力,甚至于不堪重负而瘫痪,于是我们必须对服务端开启的线程数加以控制,让机器在一个自己可以承受的范围内运行。 

      而解决的办法就是利用“线程池”:线程池就是用来存放线程的池子,本质还是基于多线程,只不过是对开启线程的数目加上了限制

      基于线程池的多线程的Server端的代码如下:

    # -*- coding: utf-8  -*-
    # -*- Author: WangHW -*-
    import socket
    from concurrent.futures import ThreadPoolExecutor
    
    
    def Communication(conn):
        # 通信循环
        while 1:
            try:
                data = conn.recv(1024)
                if not data:
                    break
                print('Client Data:', data.decode('utf-8'))
                conn.send(data.upper())
            except ConnectionResetError:
                break
    
    def Server(ip,post):
        whw_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        whw_server.bind((ip,post))
        whw_server.listen(5)
        # 链接循环
        while 1:
            conn, addr = whw_server.accept()
    
            pool.submit(Communication,conn)
    
    if __name__ == '__main__':
        #最多可开client端为2个
        pool = ThreadPoolExecutor(2)
    
        #主线程干Server的工作
        Server('127.0.0.1',9000)
    Server-线程池

      我们在线程池设置了最多可以有2个客户端与服务器端通信,所以当第三个客户端试图去与服务器端建立链接时是没有用的,只有当其中的一个客户端停掉才能通信

  • 相关阅读:
    如何用正确的方法写出高质量软件的75条体会(转)
    使用javascript动态添加onclick事件,
    签名和重载
    C#文件后缀名详解
    配置SQL Server 2005 Express的身份验证方式,以及如何启用sa登录名。
    CSS选择符及优先级计算
    关于软件版本的解释
    数据结构形象解释
    CSS属性选择符
    [转载]Repeater三层嵌套
  • 原文地址:https://www.cnblogs.com/paulwhw/p/9123062.html
Copyright © 2020-2023  润新知