• socketserver 模块 实现多并发


    socketserver 模块:
    首先,要自定义类继承socketserver.BaseRequestHandler
    这个类中的属性:
    self.request : 连接对象
    self.client_address : 客户端地址
    创建好类之后,
    server = socketserver.ThreadingTCPServer(('127.0.0.1',8083),Myserver)
    产生server这个服务端对象,第一个参数服务端地址,第二个,关联这个类,得到连接对象,要用这个类处理。
    所以,不用bind地址,
    最后,
    server.serve_forever()
    不断地从半连接池中取出连接对象,交给一个线程进行处理。

    TCP协议:
    服务端

    from socket import *
    import subprocess
    import struct
    import socketserver
    
    class Myserver(socketserver.BaseRequestHandler):
        def handle(self):
            # self.client_address
            # self.request
                # 第二件事:拿到链接对象,与其进行通信循环
            while True:
                try:
                    data = self.request.recv(1024)  # 最大接收的数据量为1024Bytes,收到的是bytes类型
                    if len(data) == 0:
                        # 在unix系统洗,一旦data收到的是空
                        # 意味着是一种异常的行为:客户度非法断开了链接
                        break
                    result = subprocess.Popen(data.decode('utf-8'), shell=True, stdout=subprocess.PIPE,
                                              stderr=subprocess.PIPE)
                    out = result.stdout.read()
                    err = result.stderr.read()
                    self.request.send(struct.pack('i', len(out) + len(err)))
                    self.request.send(out)
                    self.request.send(err)
                    print("客户端发来的消息:", data.decode('utf-8'))
                except Exception:
                    # 针对windows系统
                    break
    
            # 6、关闭电话连接conn(必选的回收资源的操作)
            self.request.close()
                # 7、关机(可选操作)     要实现不断地从半连接池中取出连接请求,服务器不能关闭
                # phone.close()
    
    server = socketserver.ThreadingTCPServer(('127.0.0.1',8080),Myserver)
    server.serve_forever()
    # phone=socket(AF_INET,SOCK_STREAM) # 流式协议=》tcp协议
    # phone.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) #就是它,在bind前加
    # phone.bind(('127.0.0.1',8083)) # 0-65535, 1024以前的都被系统保留使用
    # phone.listen(5) # 5指的是半连接池的大小
    
    #  服务端应该做两件事
    # 第一件事:循环地从板连接池中取出链接请求与其建立双向链接,拿到链接对象
    

    客户端:

    import socket
    import struct
    
    phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) # 流式协议=》tcp协议
    phone.connect(('127.0.0.1',8080))
    while True:
        msg=input("命令>>>: ").strip() #msg=''
        if len(msg) == 0:continue
        phone.send(msg.encode('utf-8'))
        top = phone.recv(4)
        top_len = struct.unpack('i',top)
        size = 0
        while size < top[0]:
            data=phone.recv(1024)
            print(data.decode('gbk'),end='')
            size += len(data)
    
    #4、关闭连接(必选的回收资源的操作)
    phone.close()
    

    UDP协议:
    服务端:

    import socketserver
    
    class MyRequestHanlde(socketserver.BaseRequestHandler):
        def handle(self):
            client_data=self.request[0]
            server=self.request[1]
            client_address=self.client_address
            print('客户端发来的数据%s' %client_data)
            server.sendto(client_data.upper(),client_address)
    
    
    s=socketserver.ThreadingUDPServer(("127.0.0.1",8888),MyRequestHanlde)
    s.serve_forever()
    # 相当于:只负责循环地收
    # while True:
    #     data,client_addr=server.recvfrom(1024)
    #     启动一个线程处理后续的事情(data,client_addr)
    

    客户端:

    import socket
    
    client=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) # 流式协议=》tcp协议
    
    while True:
        msg=input('>>>: ').strip()
        client.sendto(msg.encode('utf-8'),('115.29.65.16',8888))
        res=client.recvfrom(1024)
        print(res)
    
    client.close()
    
  • 相关阅读:
    html5与css交互 API 《一》classList
    HTML5标签速查
    html5中常被忘记的标签,属性
    html5不熟悉的标签全称
    基于HTML5的网络拓扑图(1)
    HTML5 Canvas绘制效率如何?
    前端性能优化(Application Cache篇)
    Android独立于Activity或者Fragment的LoadingDialog的实现
    android常用设计模式的理解
    android使用android:ellipsize="end"无效的解决方法
  • 原文地址:https://www.cnblogs.com/pythonwl/p/12747239.html
Copyright © 2020-2023  润新知