zoukankan      html  css  js  c++  java
  • python之网络编程

    python之网络编程

    一、网络开发架构

    1.1、C/S架构:

    常见的:QQ、微信

    • 优点:

      • 可以离线使用/功能更完善/安全性更高
    • client 客户端

      • 我们需要安装的
    • server端

      • 在服务器

    1.2、B/S架构:

    • 优点:
      • 不用安装就可以使用
      • 统一PC端用户的入口

    常见的:百度、博客园、谷歌

    • B:browser 浏览器
    • S:server 服务端

    1.3、C/S架构和B/S架构有什么关系?

    B/S架构也是C/S架构中的一种

    二、网络编程之socket(抽象层)

    ​ Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。

    三、什么是粘包

    须知:只有TCP有粘包现象,UDP永远不会粘包,为何,且听我娓娓道来

    首先需要掌握一个socket收发消息的原理(实际上是跟自己打交道,自己先去自己的缓存找数据)

    • 两种会出现粘包的原因

      • tcp是流式协议,数据像水流一样连在一起,没有分界
      • 收数据没收干净,有残留,就会跟下次结果混在一起
    • 解决的核心法则

      • 每次都收干净,别有残留

      • 1、拿到数据的总大小 total_size
        2、循环接受,每次接收一次,recv_size+=接收的长度
        3、直到recv_size=total_size,结束循环cpp
        

    服务端代码:

    import subprocess
    import struct
    import json
    from socket import *
    
    server = socket(AF_INET,SOCK_STREAM)
    server.bind(('112.74.113.107',22))
    server.listen()
    
    #服务端做2件事
    # 1、循环从半连接池取数据、且建立双向链接,拿到链接对象(conn)
    while True:
        conn,client_addr = server.accept()
        # 2、拿到链接对象,与其通信循环
        while True:
            try:
                cmd = conn.recv(1024)
                if len(cmd) == 0:
                    break
                obj = subprocess.Popen(cmd.decode('utf-8'),
                                 shell=True,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE
                                 )
                stdout_res = obj.stdout.read()  #bash 类型
                stderr_res = obj.stderr.read()
    
                #数据总大小
                total_size = len(stdout_res) + len(stderr_res)
    
                # 1、制作头
                header_dic = {
                    "filename":"a.txt",
                    "total_size":total_size,
                    "md5":"xxxxxxxx"
                }
    
                json_str = json.dumps(header_dic)
                json_str_bytes = json_str.encode("utf-8")
    
                # 2、先发固定长度的bbytes:对数据描述信息 pack打包 i --> 4个字节大小
                xxxx = struct.pack('i',len(json_str_bytes))
                conn.send(xxxx)
    
                # 3、发头信息
                conn.send(json_str_bytes)
    
                # 4、再发真实的数据
                conn.send(stdout_res)
                conn.send(stderr_res)
    
                #不建议这样写
                #conn.send(stdout_res+stderr_res)
                #文件的写法
                # with open("xx.mp4",mode='rb') as f:
                #     for line in f:
                #         conn.send(line)
    
                # print(cmd.decode('utf-8'))
                # print(client_addr)
            except Exception:
                break
        conn.close()
    

    客户端代码:

    import json
    import struct
    from socket import *
    
    client = socket(AF_INET,SOCK_STREAM)
    client.connect(('112.74.113.107',22))
    
    while True:
        msg = input('请输入命令').strip()
        if len(msg) == 0:
            continue
        client.send(msg.encode('utf-8'))
    
        #解决粘包的问题思路:
        # 一、收固定长度的头:解析出数据的描述信息,拿到数据的总大小
            # 1、拿到头信息
        xxxx = client.recv(4)
        header_len = struct.unpack('i',xxxx)[0]
            # 2、接收头,且解析
        json_str_bytes = client.recv(header_len)
        json_str = json_str_bytes.decode('utf_8')
        header_dic = json.loads(json_str)
        print(header_dic)
        total_size = header_dic["total_size"]
    
    
        # 二、根据解析出的头描述信息,接受真实数据
            # 2、循环接受,每次接收一次,recv_size+=接收的长度
            # 3、直到recv_size=total_size,结束循环
        recv_size = 0
        while recv_size < total_size:
            recv_data = client.recv(1024)
            recv_size += len(recv_data)
            print(recv_data.decode('gbk'),end='')
        else:
            print()
        # cmd_res = client.recv(1024)
        # print(cmd_res.decode('gbk'))
    
  • 相关阅读:
    C# 图片与Base64的相互转化
    LeetCode 303. Range Sum Query – Immutable
    LeetCode 300. Longest Increasing Subsequence
    LeetCode 292. Nim Game
    LeetCode 283. Move Zeroes
    LeetCode 279. Perfect Squares
    LeetCode 268. Missing Number
    LeetCode 264. Ugly Number II
    LeetCode 258. Add Digits
    LeetCode 257. Binary Tree Paths
  • 原文地址:https://www.cnblogs.com/hsyw/p/13773649.html
Copyright © 2011-2022 走看看