zoukankan      html  css  js  c++  java
  • 网络编程(套接字)之粘包、报头等相关内容-32

    1.socket接入多个客户端

    # server.py

    from socket import *

    server = socket(AF_INET, SOCK_STREAM)
    # print(server)
    server.bind(('127.0.0.1', 8080))
    server.listen(5)
    while True:
       conn, client_addr = server.accept()
       print(conn)
       print(client_addr)

       while True:
           try:
               data = conn.recv(1024)
               conn.send(data.upper())
           except Exception:
               break
       conn.close()

    server.close()


    # client.py

    from socket import *

    client = socket(AF_INET, SOCK_STREAM)
    # print(client)
    client.connect(('127.0.0.1', 8080))

    while True:
       cmd = input(">>: ").strip()
       if len(cmd) == 0:
           continue
       client.send(cmd.encode('utf-8'))
       print('=======>')
       data = client.recv(1024)
       print('111111')
       print(data.decode('utf-8'))
    client.close()

    2.远程执行命令程序解决粘包问题

    # server.py

    import subprocess
    import struct
    from socket import *

    server = socket(AF_INET, SOCK_STREAM)
    # print(server)
    server.bind(('127.0.0.1', 8082))
    server.listen(5)
    while True:
       conn, client_addr = server.accept()
       print(conn)
       print(client_addr)

       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.stdout.read()
               total_size = len(stdout) + len(stderr)

               # 先发送数据的长度
               conn.send(struct.pack('i', total_size))
               # 发送真正的数据
               conn.send(stdout)
               conn.send(stderr)
           except Exception:
               break
       conn.close()

    server.close()


    # client.py

    import struct
    from socket import *

    client = socket(AF_INET, SOCK_STREAM)
    # print(client)
    client.connect(('127.0.0.1', 8082))

    while True:
       cmd = input(">>: ").strip()
       if len(cmd) == 0:
           continue
       client.send(cmd.encode('utf-8'))

       # 先收数据的长度
       n = 0
       header = b''
       while n < 4:
           data = client.recv(1)
           header += data
           n += len(data)

       total_size = struct.unpack('i', header)[0]

       # 收真正的数据
       recv_size = 0
       res = b''
       while recv_size < total_size:
           data = client.recv(1024)
           res += data
           recv_size += len(data)

       print(res.decode('gbk'))

    client.close()

    3.定制复杂的报头

    # server.py

    import subprocess
    import os
    import struct
    from socket import *

    server = socket(AF_INET, SOCK_STREAM)
    # print(server)
    server.bind(('127.0.0.1', 8082))
    server.listen(5)
    while True:
       conn, client_addr = server.accept()
       print(conn)
       print(client_addr)

       while True:
           try:
               msg = conn.recv(1024).decode('utf-8')
               cmd,file_path=msg.split()
               if cmd == "get":
                   # 先发送报头
                   total_size=os.path.getsize(file_path)
                   conn.send(struct.pack('q',total_size))
                   # 再发送文件
                   with open(r'%s' %file_path,mode='rb') as f:
                       for line in f:
                           conn.send(line)
           except Exception:
               break
       conn.close()

    server.close()


    # client.py

    import struct
    from socket import *

    client = socket(AF_INET, SOCK_STREAM)
    # print(client)
    client.connect(('127.0.0.1', 8082))

    while True:
       cmd = input(">>: ").strip()  # get 文件路径
       if len(cmd) == 0:
           continue
       client.send(cmd.encode('utf-8'))

       # 先收数据的长度
       n = 0
       header = b''
       while n < 8:
           data = client.recv(1)
           header += data
           n += len(data)

       total_size = struct.unpack('q', header)[0]
       print(total_size)
       # 收真正的数据
       recv_size = 0
       with open('aaa.jpg', mode='wb') as f:
           while recv_size < total_size:
               data = client.recv(1024)
               f.write(data)
               recv_size += len(data)


    client.close()
    # server.py

    import subprocess
    import os
    import struct
    import json
    from socket import *

    server = socket(AF_INET, SOCK_STREAM)
    # print(server)
    server.bind(('127.0.0.1', 8082))
    server.listen(5)
    while True:
       conn, client_addr = server.accept()
       print(conn)
       print(client_addr)

       while True:
           try:
               msg = conn.recv(1024).decode('utf-8')
               cmd,file_path=msg.split()
               if cmd == "get":
                   # 一、制作报头
                   header_dic={
                       "total_size":os.path.getsize(file_path),
                       "filename":os.path.basename(file_path),
                       "md5":"1231231231232132131232311"
                  }
                   header_json=json.dumps(header_dic)
                   header_json_bytes=header_json.encode('utf-8')


                   # 二、发送数据
                   # 1、先发送报头的长度
                   header_size=len(header_json_bytes)
                   conn.send(struct.pack('i',header_size))
                   # 2、再发送报头
                   conn.send(header_json_bytes)
                   # 3、最后发送真实的数据
                   with open(r'%s' %file_path,mode='rb') as f:
                       for line in f:
                           conn.send(line)
           except Exception:
               break
       conn.close()

    server.close()

    # client.py

    import struct
    import json
    from socket import *

    client = socket(AF_INET, SOCK_STREAM)
    # print(client)
    client.connect(('127.0.0.1', 8082))

    while True:
       cmd = input(">>: ").strip()  # get 文件路径
       if len(cmd) == 0:
           continue
       client.send(cmd.encode('utf-8'))

       # 1、先接收报头的长度
       res=client.recv(4)
       header_size=struct.unpack('i',res)[0]
       # 2、再接收报头
       header_json_bytes=client.recv(header_size)
       header_json=header_json_bytes.decode('utf-8')
       header_dic=json.loads(header_json)
       print(header_dic)
       # 3、最后接收真实的数据
       total_size=header_dic['total_size']
       filename=header_dic['filename']
       recv_size = 0
       with open(r"D:python全栈15期day32代码3 定制复杂的报头版本2download\%s" %filename, mode='wb') as f:
           while recv_size < total_size:
               data = client.recv(1024)
               f.write(data)
               recv_size += len(data)


    client.close()

     

  • 相关阅读:
    springboot集成kafka
    elasticsearch http 搜索 测试
    linux下安装Elasticsearch
    laravel_admin 使用
    laravel 数据操作
    Win10+apache+PHP+Mysql
    laravel 坑(一)
    下载CentOS镜像
    window10 家庭版 添加Hyper-V虚拟机
    Win10 Composer 下载安装
  • 原文地址:https://www.cnblogs.com/usherwang/p/13515791.html
Copyright © 2011-2022 走看看