• day 27


    一.基于tcp协议的通信套接字(循环链接)

    服务端代码:
    from socket import *
    
    server = socket(AF_INET, SOCK_STREAM)
    server.bind(("127.0.0.1", 8081))
    server.listen(5)
    # 链接循环
    while True:
        conn, addr = server.accept()
        # 通信循环
        while True:
            try:      #try 与 except 的作用是:当客户端单方面的断开连接是,接收异常,并断开连接,结束此次服务,但服务器的服务不会断开
                data = conn.recv(1024)
                print(data.decode("utf-8"))
                msg = input(">>>:").strip()
                conn.send(msg.encode("utf-8"))
            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:
        data1= input(">>>:").strip()
        if len(data1)==0:continue
        client.send(data1.encode("utf-8"))
        data=client.recv(1024)
        print(data.decode("utf-8"))
    
    client.close()

    二.模拟ssh实现远程执行命令(会出现粘包问题)

    服务端代码:
    from socket import *
    import subprocess
    
    server = socket(AF_INET, SOCK_STREAM)
    server.bind(("127.0.0.1", 8081))
    server.listen(5)
    # 连接循环
    while True:
        conn, addr = server.accept()
        # 通信循环
        while True:
            try:
                # 接收信息:
                cmd = conn.recv(1024)
                obj = subprocess.Popen(cmd.decode("utf-8"), shell=True,
                                       stderr=subprocess.PIPE,
                                       stdout=subprocess.PIPE
                                       )
                stdout = obj.stdout.read()
                stderr = obj.stderr.read()
                # 发送消息
                conn.send(stderr + stdout)
            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:
        # 发送消息
        cmd = input(">>>:").strip()
        if len(cmd) == 0: continue
        client.send(cmd.encode("utf-8"))
        # 接受信息
        data1=client.recv(1024)
        print(data1.decode("gbk"))
        
    client.close()

    三.模块struct

    import  struct
    
    data=struct.pack("i",12312)
    print(data,len(data))   #会将一定长度的整型,变成长度固定的字节
    
    data1=struct.unpack("i",data)
    print(data1[0])
    
    #粘包问题:是tcp协议流式传输数据的方式导致的
    #解决粘包问题:接收端能够精确的收干净每个数据包,没有残留

    四.二.模拟ssh实现远程执行命令(解决现粘包问题的初级方法)

    服务端代码:
    from socket import  *
    import  subprocess
    import  struct
    
    server= socket(AF_INET,SOCK_STREAM)
    server.bind(("127.0.0.1",8081))
    server.listen(5)
    #链接循环
    while True:
        conn,addr = server.accept()
        #通信循环
        while True:
            try:
                #接收信息
                cmd = conn.recv(1024)
                obj=subprocess.Popen(cmd.decode("utf-8"),
                                     shell=True,
                                     stdout=subprocess.PIPE,
                                     stderr=subprocess.PIPE,
                                     )
                stdout=obj.stdout.read()
                stderr=obj.stderr.read()
                header= struct.pack("i",len(stdout)+len(stderr))
                #先发送报头长度:(统一为四个字节)
                conn.send(header)
                #再发送真实数据:
                conn.send(stderr+stdout)
            except ConnectionResetError:
                break
        conn.close()
    
    server.close()
    
    
    
    客户端代码:
    from socket import  *
    import  struct
    
    client = socket(AF_INET,SOCK_STREAM)
    client.connect(("127.0.0.1",8081))
    #通信连接
    while True:
        #发送命令
        cmd = input(">>>:").strip()
        if len(cmd)==0:continue
        client.send(cmd.encode("utf-8"))
        #接收信息:
        # 1. 先接收报头的信息
        header=client.recv(4)
        tottal_size=struct.unpack("i",header)[0]   #为真实数据的长度
        # 2. 再接收真正的数据
        cmd_res=b""
        size_cmd=0
        while size_cmd<tottal_size:
            data=client.recv(1024)
            size_cmd += len(data)
            cmd_res += data
        print(cmd_res.decode('gbk'))
    
    client.close()


    五.模拟ssh实现远程执行命令(解决现粘包问题的终级方法)

    服务端代码:
    from socket import  *
    import  struct
    import json
    import subprocess
    
    server=socket(AF_INET,SOCK_STREAM)
    server.bind(("127.0.0.1",8081))
    server.listen(5)
    #链接循环
    while True:
        conn,addr=server.accept()
        #通信循环
        while True:
            try:
                cmd = server.recv(1024)
                obj=subprocess.Popen(cmd.decode("utf-8"),shell=True,
                                     stdout=subprocess.PIPE,
                                     stderr=subprocess.PIPE,
                                     )
                stdout=obj.stdout.read()
                stderr=obj.stderr.read()
                 # 1 制作报头:
                header_dic ={
                    "filename":"a.txt",
                    "md5":"erhwer",
                    "header_size":len(stdout)+len(stderr)
                }
                # 对报头序列化
                header_json=json.dumps(header_dic)   #对应写
                #将序列化好的报头转为字节
                header_bytes=header_json.encode("utf-8")
                # 2 先发送4个bytes(包含报头的长度)
                conn.send(struct.pack("i",len(header_bytes)))
                # 3 再发送报头
                conn.send(header_bytes)
                # 4 发送真实的数据
                conn.send(stderr+stdout)
            except ConnectionResetError:
                break
        conn.close()
    
    server.close()
    
    客户端代码:
    from socket import  *
    import struct
    import  json
    
    client = socket(AF_INET,SOCK_STREAM)
    client.connect(("127.0.0.1",8081))
    #通信循环
    while True:
        #发送命令
        cmd = input(">>>:").strip()
        if len(cmd)==0:continue
        client.send(cmd.encode("utf-8"))
        #接收信息
        # 1 先收四个bytes 再解出报头长度
        header_size=struct.unpack("i",client.recv(4))[0]
        # 2 再接收报头,拿到header_dic
        header_bytes=client.recv(header_size)
        header_json=header_bytes.decode("utf-8")
        header_dic=json.loads(header_json)
        tottal_size=header_dic["header_size"]
        #接收真实的数据
        cmd_res= b""
        res_size=0
        while res_size < tottal_size:
            data=client.recv(1024)
            cmd_res += data
            res_size += len(data)
        print(cmd_res.decode("gbk"))
    
    client.close()
  • 相关阅读:
    Android插件化技术简介
    Fragment回退栈&commit()和commitAllowingStateLoss()
    Android热更新技术——Tinker、nuwa、AndFix、Dexposed
    Object的wait/notify/notifyAll&&Thread的sleep/yield/join/holdsLock
    synchronized与Lock的区别与使用
    多分类Logistics回归公式的梯度上升推导&极大似然证明sigmoid函数的由来
    从损失函数的角度详解常见机器学习算法
    LR的损失函数&为何使用-log损失函数而非平方损失函数
    css Cascading Style Sheet 层叠样式表
    前端—— 前端介绍开始(二)
  • 原文地址:https://www.cnblogs.com/jxl123/p/9579584.html
Copyright © 2020-2023  润新知