zoukankan      html  css  js  c++  java
  • 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)
  • 相关阅读:
    Swift语法基础: 20
    Swift语法基础:19
    Swift语法基础:18
    Swift语法基础:17
    Swift语法基础:16
    Swift语法基础:15
    Swift语法基础:14
    Swift语法基础:13
    Swift语法基础:12
    Swift语法基础:11
  • 原文地址:https://www.cnblogs.com/beargod/p/10235106.html
Copyright © 2011-2022 走看看