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'))
    
  • 相关阅读:
    斜率dp cdq 分治
    POJ2449 (k短路)
    BZOJ1576 (最短路+并查集)
    SWUST0249 (凸包面积)
    道路修建 (网络流)
    HDU3930 (原根)
    ZOJ2006 (后缀自动机)
    Codechef2015 May
    后缀自动机
    Digit (数位DP)
  • 原文地址:https://www.cnblogs.com/hsyw/p/13773649.html
Copyright © 2011-2022 走看看