• Day32、基于tcp通信的套接字,连接与通信循环,粘包问题,远程控制


    一、基于tcp通信的套接字程序

    服务端:

    from socket import *
    
    # 服务端必须满足至少三点:
    # 1.绑定一个固定的ip和port
    # 2.一直对外提供服务,稳定运行
    # 3.能够支持并发
    server = socket(AF_INET, SOCK_STREAM)
    server.bind(('127.0.0.1', 9555))
    server.listen(5)
    
    client, addr = server.accept()
    data = client.recv(1024)
    print(data.decode('utf-8'))
    client.send(data.upper())
    
    client.close()
    server.close()

    客户端:

    from socket import *
    client = socket(AF_INET,SOCK_STREAM)
    client.connect(('127.0.0.1',9555))
    
    msg = input('>>>:').strip()
    client.send(msg.encode('utf-8'))
    data = client.recv(1024)
    print(data)
    
    client.close()

    二、修改bug + 通信循环 + 连接循环

      上述存在客户端退出时服务端即会崩溃的bug,而且无法实现用户的多次输入,以及服务端无法一直对外服务的问题,对此进行修改

    服务端:

    from socket import *
    
    server = socket(AF_INET, SOCK_STREAM)
    server.bind(('127.0.0.1', 8081))
    server.listen(5)
    
    # 链接循环
    while True:
        conn, client_addr = server.accept()
        print(client_addr)
    
        # 通信循环
        while True:
            try:
                data = conn.recv(1024)
                if len(data) == 0: break  # 针对linux系统
                print('-->收到客户端的消息: ', data)
                conn.send(data.upper())
            except ConnectionResetError:
                break
    
        conn.close()
    
    server.close()

    客户端:

    from socket import *
    
    client = socket(AF_INET, SOCK_STREAM)
    client.connect(('127.0.0.1', 8081))
    
    # 通信循环
    while True:
        msg=input('>>: ').strip() #msg=''
        if len(msg) == 0:continue
        client.send(msg.encode('utf-8')) #client.send(b'')
        # print('has send')
        data=client.recv(1024)
        # print('has recv')
        print(data)
    
    client.close()

    三、粘包问题解决方案

    服务端:

    import socket
    import subprocess
    import struct
    import json
    
    IP = '127.0.0.1'
    PORT = 8383
    ADDRESS = (IP, PORT)
    BUFSIZE = 1024
    
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    
    server.bind(ADDRESS)
    
    server.listen(5)
    tag = True
    while tag:
        conn, addr = server.accept()
        while tag:
            try:
                data = conn.recv(BUFSIZE)
                if not data:
                    print('服务端断开。。。。')
                    break
                # 获取sub对象
                res = subprocess.Popen(data.decode("utf-8"),
                                       shell=True,
                                       stdout=subprocess.PIPE,
                                       stderr=subprocess.PIPE)
                print('>>>>', data.decode('utf-8'))
                # 成功的结果
                stdout = res.stdout.read()
                # 失败的结果
                stderr = res.stderr.read()
    
                # 1.制作报头
                header_dic = {
                    'filename': 'a.txt',
                    'md5': 'sd7a86d87sad6as',
                    'total_size': len(stdout) + len(stderr)
                }
                header_json = json.dumps(header_dic)
                header_bytes = header_json.encode('utf-8')
    
                # 2.先发送报头长度
                conn.send(struct.pack('i', len(header_bytes)))
    
                # 3.再发送报头
                conn.send(header_bytes)
    
                # 4.最后发送数据
                conn.send(stdout)
                conn.send(stderr)
            except ConnectionResetError:
                break
        conn.close()
    server.close()

    客户端:

    import socket
    import struct
    import json
    IP = '127.0.0.1'
    PORT = 8383
    ADDRESS = (IP, PORT)
    BUFSIZE = 1024
    
    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    
    client.connect(ADDRESS)
    while True:
    
        msg = input('>>>')
        if len(msg) == 0: continue
        client.send(msg.encode('utf-8'))
    
        # 1.先获取报头长度
        header_size = struct.unpack('i',client.recv(4))[0]
    
        #2.在获取报头
        header_bytes=client.recv(header_size)
        header_json=header_bytes.decode('utf-8')
        header_dic=json.loads(header_json)
        print(header_json)
        total_size=header_dic['total_size']
    
        # 3.在获取真正数据
        cmd_res=b''
        recv_size=0
        while recv_size<total_size:
            data=client.recv(1024)
            recv_size+=len(data)
            cmd_res+=data
        print(cmd_res.decode('gbk'))
    
    client.close()

    四、远程控制

    服务端:

    from socket import *
    
    import subprocess
    
     
    
    # 服务器必须满足至少三点
    
    # 1. 绑定一个固定的ip和port
    
    # 2. 一直对外提供服务,稳定运行
    
    # 3. 能够支持并发
    
     
    
    server = socket(AF_INET, SOCK_STREAM)
    
     
    
    server.bind(('192.168.13.235', 8080))
    
     
    
    server.listen(5)
    
     
    
    # 链接循环
    
    while True:
    
        conn, client_addr = server.accept()
    
     
    
        # 通信循环
    
        while True:
    
            # 捕捉异常防止客户端断开链接导致服务器报错
    
            try:
    
                data = conn.recv(1024)
    
     
    
                
    
                obj = subprocess.Popen(data.decode('utf-8'),
    
                                       shell=True,
    
                                       stdout=subprocess.PIPE,
    
                                       stderr=subprocess.PIPE
    
                                       )
    
                stdout = obj.stdout.read()
    
                stderr = obj.stderr.read()
    
     
    
                conn.send(stdout)
    
     
    
            except ConnectionResetError:
    
                break
    
     
    
        conn.close()
    
    server.close()
    View Code

    客户端:

    from socket import *
    
    import subprocess
    
     
    
    # 服务器必须满足至少三点
    
    # 1. 绑定一个固定的ip和port
    
    # 2. 一直对外提供服务,稳定运行
    
    # 3. 能够支持并发
    
     
    
    server = socket(AF_INET, SOCK_STREAM)
    
     
    
    server.bind(('192.168.13.235', 8080))
    
     
    
    server.listen(5)
    
     
    
    # 链接循环
    
    while True:
    
        conn, client_addr = server.accept()
    
     
    
        # 通信循环
    
        while True:
    
            # 捕捉异常防止客户端断开链接导致服务器报错
    
            try:
    
                data = conn.recv(1024)
    
     
    
                
    
                obj = subprocess.Popen(data.decode('utf-8'),
    
                                       shell=True,
    
                                       stdout=subprocess.PIPE,
    
                                       stderr=subprocess.PIPE
    
                                       )
    
                stdout = obj.stdout.read()
    
                stderr = obj.stderr.read()
    
     
    
                conn.send(stdout)
    
     
    
            except ConnectionResetError:
    
                break
    
     
    
        conn.close()
    
    server.close()
    View Code
  • 相关阅读:
    一位老司机开车20年后得到的26条教训
    H608B无线路由破解方法
    我们去工作到底为了什么?
    什么是”中国梦”?
    Cubieboard A10 安装Nand系统,配置nginx,php,mysql,samba详细教程
    早晚有一天,我们都会成为自己当初讨厌的人
    当下中国的十二种孤独
    终于见到全文了,太唯美了!
    想生男想生女 从科学角度为你解读
    如何找到板块中所有个股
  • 原文地址:https://www.cnblogs.com/Mister-JH/p/9580647.html
Copyright © 2020-2023  润新知