zoukankan      html  css  js  c++  java
  • (23)socket多进程并发

    # 对于服务器自己本身,一个程序只能绑定一个端口

    # 同一个端口可以多个客户端来连接,

    # 只要server_ip+ server_port +client_ip + cilent_port 不一样,就是唯一

    客户端我这里只写一个,基本大同小异,下面的都是服务端的

    client:

    import socket
    sk = socket.socket()
    sk.connect(('127.0.0.1',9000))
    while True:
        print(sk.recv(1024))
        sk.send(b'bye')
    sk.close()
    View Code

    (1) Process模块开子进程实现

    server:

    import socket
    from multiprocessing import Process
    
    def communicate(conn):
        while True:
            conn.send(b'hello')
            print(conn.recv(1024))
    if __name__ == "__main__":
        sk = socket.socket()
        # 对于服务器自己本身,一个程序只能绑定一个端口
        # 同一个端口可以多个客户端来连接,
        # 只要server_ip+ server_port +client_ip + cilent_port 不一样,就是唯一
        sk.bind(("127.0.0.1", 9000))
        sk.listen()
        while True:
            conn, addr = sk.accept()
            Process(target=communicate, args=(conn,)).start()
    View Code

    执行效果图:同时可以连接多个客户端

    (2)socketserver模块实现

    功能:实现TCP同时连接多个客户端

    并发:一个cpu同时不停地执行多个程序

    server:

    import socketserver
    
    
    # 自定义一个类 MyServer
    class MyServer(socketserver.BaseRequestHandler):
        # handle 方法是每当有一个客户端发起connect来接之后,自动执行handle
        def handle(self):
            # self.request  # 相当于conn
            # self.client_address # 相当于addr
            conn = self.request
            while True:
                print(conn.recv(1024))
                conn.send(b'hello')
    #  避免端口报错
    socketserver.TCPServer.allow_reuse_address = True
    # ip 端口号  |  自定义类
    server = socketserver.ThreadingTCPServer(("127.0.0.1", 9000), MyServer)
    # 循环调用
    server.serve_forever()
    View Code

    (3) 进程池实现

    server:

    import socket
    from multiprocessing import Pool
    def talk(conn):
        while True:
            conn.send(b"hello")
            print(conn.recv(1024))
        conn.close()
    if __name__ == "__main__":
        sk = socket.socket()
        sk.bind(("127.0.0.1", 9000))
        sk.listen()
        # Pool默认获取cpu_counter cpu最大核心数 我的机器是6
        p = Pool()
        while True:
            conn, addr = sk.accept()
            p.apply_async(talk, args=(conn,))
        sk.close()
    View Code

    (4) 多线程实现

    server:

    import socket
    from threading import Thread
    def func(conn):
        while True:
            conn.send(b"hello")
            print(conn.recv(1024))
        conn.close()
    if __name__ == '__main__':
        sk = socket.socket()
        sk.bind(('127.0.0.1',9000))
        sk.listen()
        while True:
            conn,addr = sk.accept()
            t = Thread(target=func,args=(conn,))
            t.start()
        sk.close()
    View Code

    (5) 协程实现 gevent

    server:

    from gevent import monkey; monkey.patch_all()
    import socket
    import gevent
    import os 
    from threading import current_thread as cthread
    import time
    
    def talk(conn):
        while True:
            print(cthread().ident,os.getpid())
            time.sleep(0.1)
            conn.send(b'hello')
            print(conn.recv(1024))
    
    sk = socket.socket()
    sk.bind( ("127.0.0.1" ,9000))
    sk.listen()
    
    # 用一个线程接受了所有访问的连接.(因为利用了协程)
    while True:
        conn,addr = sk.accept()
        # spawn 和 submit 用法一样 参数默认往后写就可以了
        gevent.spawn(talk,conn)
    View Code

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

  • 相关阅读:
    过河问题 (Standard IO)
    单词分类 (Standard IO)
    C#综合揭秘——细说多线程(上)
    使用NPOI导入导出标准Excel
    C# 转义字符 ''反斜杠
    ref和out的区别
    抽象类接口的区别
    方法签名
    SQL Server的通用分页存储过程 未使用游标,速度更快!
    SQL Server存储过程Return、output参数及使用技巧
  • 原文地址:https://www.cnblogs.com/lyj910313/p/10787430.html
Copyright © 2011-2022 走看看