zoukankan      html  css  js  c++  java
  • CSIC_716_20191203【 socket网络编程,以及沾包问题的高级解决方式】

    • AF_UNIX(本机通信)
    • AF_INET(TCP/IP – IPv4)
    • AF_INET6(TCP/IP – IPv6)
    • SOCK_STREAM(TCP流)
    • SOCK_DGRAM(UDP数据报)

    远程操作服务端的命令行。

    解决沾包问题的方法:   以远程连接服务端的命令行为例子。

    server服务端

    # _*_ coding: gbk _*_
    # @Author: Wonder
    import socket
    import json
    import subprocess
    import struct  # 将数字类型变成固定长度,
    from socket import SOL_SOCKET, SO_REUSEADDR
    
    sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sk.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)  # 重用地址
    
    sk.bind(('127.0.0.1', 9900))  # 绑定地址和端口号   ,这里ip和端口组成一个元组
    sk.listen(5)  # 启动监听,允许最大连接数量为3
    while True:
        sock, addr = sk.accept()  # 三次握手建立的管道,支持多个客户端client进行连接
        while True:
            try:
                bin_cmd = sock.recv(1024)  # 二进制, 接收二进制的cmd
                cmd = bin_cmd.decode('utf-8')  # 转成真是的cmd
                sub_obj = subprocess.Popen(cmd, shell=True,
                                           stdout=subprocess.PIPE,
                                           stderr=subprocess.PIPE)  # 操作本机cmd
                stdout = sub_obj.stdout.read()  # 系统生成的二进制,windows环境下是gbk编码格式,Linux下是utf-8格式。
                stderr = sub_obj.stderr.read()
                '''
                高级版本在于改造报头
                '''
                head_content = {
                    'filename': 'kazami.txt',
                    'secreatkey': 123456,
                    'header': len(stdout) + len(stderr)
                }
                head_text = json.dumps(head_content).encode('utf-8')  # 序列化之后进行编码
    
                sock.send(struct.pack('i', len(head_text)))  # 发报头长度
                sock.send(head_text)  # 发报头
    
                sock.send(stdout)
                sock.send(stderr)
                # sock.send(str2.encode('utf-8'))
            except ConnectionResetError:  # 当判断client断开连接后,跳出循环
                break
    
        sock.close()
    
    sk.close()
    

      

    client  客户端

    # _*_ coding: gbk _*_
    # @Author: Wonder
    import socket
    import struct
    import json
    
    sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # 和 Internet中的通信,流格式。
    sk.connect(('127.0.0.1', 9900))  # 连接到服务端的绑定地址
    while True:
        cmd = input('>>>').strip()
        if not cmd:
            continue
        sk.send(cmd.encode('utf-8'))  # 必须要发送二进制的数据。
        res1 = sk.recv(4)  #取报头长度
        text_text_len = struct.unpack('i', res1)[0]  # 获取报头的真实长度
        bin_head_text = sk.recv(text_text_len)  # 读取报头内容
        head_text =json.loads(bin_head_text.decode('utf-8'))
    
        print(head_text)
    
        data_size = head_text.get('header')  # 真实内容长度
    
        res_byt = b''
        real_size = 0
        while real_size < data_size:    #当真实拼接的长度小于数据长度时,不断拼接,直到完整数据拼出来。
            res = sk.recv(4444)     # 最大为缓存,过大没有意义。
            res_byt += res
            real_size += len(res)
        print(res_byt.decode('gbk'))
        print(real_size)
    sk.close()
    

      

  • 相关阅读:
    偏函数
    通过local对象的使用,分析flask中全局request对象为神魔不同的视图函数中不会混乱--协助解读flask的源码
    flask安装即web框架介绍
    事件
    文件复制工具
    非文本文件的写入
    文件读取
    sys模块
    datetime模块
    事件冒泡与捕获
  • 原文地址:https://www.cnblogs.com/csic716/p/11980443.html
Copyright © 2011-2022 走看看