• python 缓冲区 subprocess 黏包 黏包解决方案


    一.缓冲区

    二.两种黏包现象

    两种黏包现象:

    1 连续的小包可能会被优化算法给组合到一起进行发送

    黏包现象1客户端

     1 import socket
     2 BUFSIZE = 1024
     3 ip_prort = ('127.0.0.1',8001)
     4 
     5 s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
     6 
     7 res = s.connect(ip_prort)
     8 
     9 s.send('hi'.encode('utf-8'))
    10 s.send('meinv'.encode('utf-8'))

    黏包现象1服务端

     1 from socket import *
     2 ip_prot = ('127.0.0.1',8001)
     3 
     4 tcp_socket_server = socket(AF_INET,SOCK_STREAM)
     5 
     6 tcp_socket_server.bind(ip_prot)
     7 
     8 tcp_socket_server.listen(5)
     9 
    10 conn,addr = tcp_socket_server.accept()
    11 
    12 data1 = conn.recv(10)
    13 data2 = conn.recv(10)
    14 
    15 print('->>>>>',data1.decode('utf-8'))
    16 print('->>>>>',data2.decode('utf-8'))
    17 
    18 conn.close()

    2 第一次如果发送的数据大小2000B接收端一次性接受大小为1024,这就导致剩下的内容会被下一次recv接收到,导致结果错乱

    黏包现象2客户端

     1 import socket
     2 
     3 client = socket.socket()
     4 
     5 ip_prot ='127.0.0.1',8002
     6 
     7 client.connect(ip_prot)
     8 
     9 while 1:
    10     cmd = input('请输入指令')
    11 
    12     client.send(cmd.encode('utf-8'))
    13 
    14     server_cmd_result = client.recv(1025)
    15 
    16     print(server_cmd_result.decode('GBK'))

    黏包现象2服务端

     1 import socket
     2 import subprocess
     3 
     4 server = socket.socket()
     5 
     6 ip_prot = '127.0.0.1', 8002
     7 
     8 server.bind(ip_prot)
     9 
    10 server.listen()
    11 
    12 conn, addr = server.accept()
    13 
    14 while 1:
    15     from_client_cmd = conn.recv(1024)
    16 
    17     print(from_client_cmd.decode('utf-8'))
    18 
    19     sub_obj = subprocess.Popen(
    20         from_client_cmd.decode('utf-8'),  # 传入的cmd命令
    21         shell=True,
    22         stdout=subprocess.PIPE,  # 正确结果的存放位置
    23         stderr=subprocess.PIPE  # 错误结果的存放位置
    24     )
    25 
    26     std_msg = sub_obj.stdout.read()  # 获得管道里面拿到结果
    27 
    28     print('指令的执行结果长度>>>>', len(std_msg))
    29 
    30     conn.send(std_msg)

    三.黏包解决方案

    客户端

     1 import socket
     2 import struct
     3 
     4 client = socket.socket()
     5 ip_port = '127.0.0.1',8001
     6 
     7 client.connect(ip_port)
     8 
     9 while 1:
    10     cmd = input('请输入指令')
    11 
    12     # 发送指令
    13 
    14     client.send(cmd.encode('utf-8'))
    15 
    16     server_res_len = client.recv(4)
    17 
    18     msg_len = struct.unpack('i',server_res_len)[0]
    19 
    20     print('来自服务器端的消息长度',msg_len)
    21 
    22     server_cmd_result = client.recv(msg_len)
    23 
    24     print(server_cmd_result.decode('GBK'))

    服务端

     1 import socket
     2 import subprocess
     3 import struct
     4 
     5 server = socket.socket()
     6 ip_port = '127.0.0.1',8001
     7 
     8 server.bind(ip_port)
     9 
    10 server.listen()
    11 
    12 conn,addr  = server.accept()
    13 
    14 while 1:
    15     from_client_cmd = conn.recv(1024)
    16 
    17     print(from_client_cmd.decode('utf-8'))
    18 
    19     sub_obj = subprocess.Popen(
    20 
    21         from_client_cmd.decode('utf-8'),
    22         shell = True,
    23         stdout=subprocess.PIPE,
    24         stderr=subprocess.PIPE
    25     )
    26 
    27     std_msg = sub_obj.stdout.read()
    28 
    29     std_msg_len = len(std_msg)
    30 
    31     print('指令的执行结果长度>>>>',std_msg_len)
    32 
    33     msg_lenint_struct = struct.pack('i',std_msg_len)
    34 
    35     conn.send(msg_lenint_struct + std_msg)
  • 相关阅读:
    动态生成 Excel 文件供浏览器下载的注意事项
    JavaEE 中无用技术之 JNDI
    CSDN 泄露用户密码给我们什么启示
    刚发布新的 web 单点登录系统,欢迎下载试用,欢迎提建议
    jQuery jqgrid 对含特殊字符 json 数据的 Java 处理方法
    一个 SQL 同时验证帐号是否存在、密码是否正确
    PostgreSQL 数据库在 Windows Server 2008 上安装注意事项
    快速点评 Spring Struts Hibernate
    Apache NIO 框架 Mina 使用中出现 too many open files 问题的解决办法
    解决 jQuery 版本升级过程中出现 toLowerCase 错误 更改 doctype
  • 原文地址:https://www.cnblogs.com/beargod/p/10235106.html
Copyright © 2020-2023  润新知