缓冲区 subprocess 黏包 黏包的解决方案

缓冲区:  将程序和网络解耦输入缓冲区输出缓冲区
print(‘>>>>‘, server.getsockopt(SOL_SOCKET, SO_SNDBUF))  查看输出缓冲区大小
print(‘>>>>‘, server.getsockopt(SOL_SOCKET, SO_RCVBUF))  查看输入缓冲区大小

 

import subprocess

sub_obj = subprocess.Popen(
    "dir",          # 系统指令
    shell=True,     # 固定
    stdout=subprocess.PIPE,  # 标准输出 PIPE 管道,保存着指令的执行结果
    stderr=subprocess.PIPE   # 标准错误输出
)

  

两种黏包现象:1 连续的小包可能会被优化算法给组合到一起进行发送2 第一次如果发送的数据大小2000B接收端一次性接受大小为1024,这就导致剩下的内容会被下一次recv接收到,导致结果错乱
解决方案方案一:由于双方不知道对方发送数据的长度,导致接收的时候,可能接收不全,或者多接收另外一次发送的信息内容,      所以在发送真实数据之前,要先发送数据的长度,接收端根据长度来接收后面的真实数据,但是双方有一个交互确认的过程

方案二:Struct模块,打包:struct.pack(‘i’,长度)解包:struct.unpack(‘i’,字节)
服务端

import socket
import subprocess
import struct

server = socket.socket()

ip_port = (‘127.0.0.1‘, 8001)
server.bind(ip_port)
server.listen()

conn, addr = server.accept()

while 1:
    from_client_cmd = conn.recv(1024)
    print(from_client_cmd.decode(‘utf-8‘))
    # 接收到客户端 发送来的系统指令,我服务端通过subprocess模块到服务端自己的系统里面执行这条指令
    sub_obj = subprocess.Popen(
        from_client_cmd.decode(‘utf-8‘),
        shell=True,
        stdout=subprocess.PIPE,  # 正确结果位置
        stderr=subprocess.PIPE   # 错误
    )
    # 从管道里边拿出结果,通过sunprocess.Popen 的实例化对象.stdout.read()方法来获取管道中的结果
    std_msg = sub_obj.stdout.read()
    # 为了解决黏包现象,我们统计了一下消息的长度,先将消息的长度发送给客户端,客户端通过这个长度来接收后面我们要发送的真实数据
    std_msg_len = len(std_msg)
    print(‘指令的执行结果长度>>>>‘, len(std_msg))
    msg_lenint_struct = struct.pack(‘i‘,std_msg_len)
    conn.send(msg_lenint_struct+std_msg)

  

客户端

import socket
import struct
client = socket.socket()
client.connect((‘127.0.0.1‘, 8001))

while 1:
    cmd = input(‘请输入指令:‘)
    # 发送指令
    client.send(cmd.encode(‘utf-8‘))

    # 接收数据长度,首先接收4个字节长度的数据,因为这个4个字节是长度
    server_res_len = client.recv(4)
    msg_len = struct.unpack(‘i‘, server_res_len)[0]

    print(‘来自服务端的消息长度‘, msg_len)
    # 通过解包出来的长度,来接收后面的真实数据
    server_cmd_result = client.recv(msg_len)

    print(server_cmd_result.decode(‘gbk‘))

  



原文地址:https://www.cnblogs.com/YangWenYu-6/p/10267394.html

时间: 2024-10-10 01:56:37

缓冲区 subprocess 黏包 黏包的解决方案的相关文章

黏包-黏包的成因、解决方式及struct模块初识、文件的上传和下载

黏包: 同时执行多条命令之后,得到的结果很可能只有一部分,在执行其他命令的时候又接收到之前执行的另外一部分结果,这种显现就是黏包. 只有TCP协议中才会产生黏包,UDP协议中不会有黏包(udp协议中数据会直接丢失,俗称丢包) #面试 #首先只有在TCP协议中才有黏包现象,是因为TCP协议是面向流的协议, #在发送的数据传输的过程中还有缓存机制来避免数据丢失 #因此在连续发送小数据的时候,以及接收大小不符的时候,都容易产生黏包现象 #本质是不知道客户端发送的数据长度 面试中解释黏包 #连续send

Netty中粘包和拆包的解决方案

粘包和拆包是TCP网络编程中不可避免的,无论是服务端还是客户端,当我们读取或者发送消息的时候,都需要考虑TCP底层的粘包/拆包机制. TCP粘包和拆包 TCP是个“流”协议,所谓流,就是没有界限的一串数据.TCP底层并不了解上层业务数据的具体含义,它会根据TCP缓冲区的实际情况进行包的划分,所以在业务上认为,一个完整的包可能会被TCP拆分成多个包进行发送,也有可能把多个小的包封装成一个大的数据包发送,这就是所谓的TCP粘包和拆包问题. 如图所示,假设客户端分别发送了两个数据包D1和D2给服务端,

关于axis2.1.6与websphere7的包冲突问题的解决方案

1,复制axis2.1.6内的module文件夹内的所有文件到lib 并修改扩展名为.jar 2,删除module文件夹(可选,不删除也可以) 3,部署到was 4,设置was对应应用程序的类加载方案为父类最后,需要从 管理模块-->项目--->设置父类最后,其他地方修改无效(可能是was的bug) axis2的官方说明中要求把axis2.xml内的属性进行设置,特别是类加载顺序,但是请千万不要设置,如果设置为true,则会出现异常 以下为官方链接(仅参考,不要照做)http://axis.a

Linux程序设计学习笔记----网络编程之网络数据包拆封包与字节顺序大小端

网络数据包的封包与拆包 过程如下: 将数据从一台计算机通过一定的路径发送到另一台计算机.应用层数据通过协议栈发到网络上时,每层协议都要加上一个数据首部(header),称为封装(Encapsulation),如下图所示: 不同的协议层对数据包有不同的称谓,在传输层叫做段(segment),在网络层叫做数据包(packet),在链路层叫做帧(frame).数据封装成帧后发到传输介质上,到达目的主机后每层协议再剥掉相应的首部,最后将应用层数据交给应用程序处理. 上图对应两台计算机在同一网段中的情况,

MINA粘包断包专题研究

一.前述: 近期做项目用到了MINA,其中遇到了一个断包与粘包的问题,困扰了我一天一夜,经过一天一夜的思索与查看其他大牛分享的资料,现将我在解决这一问题过程中的一些心得与解决问题的方法记录下来,供广大IT兄弟姐妹们参考,如有不对或欠妥之处,请指证.请不要吝惜分享您的技术,作为中国IT软件工程师,一定要想到多一个人掌握IT技术,不会给你增加一个竞争对手,如果认为会给你增加竞争对手,这种想法是非常狭隘的,自私自利的.只有分享,大家共同的技术提高了,才能激发出更多的思维解决更加棘手的技术难点,希望大家

Java 粘包/半包 原理与拆包实战(史上最全)

疯狂创客圈 Java 聊天程序[ 亿级流量]实战系列之13 [博客园 总入口 ] 本文的源码工程:Netty 粘包/半包原理与拆包实战 源码 本实例是<Netty 粘包/半包原理与拆包实战> 一文的源代码工程. 写在前面 大家好,我是作者尼恩. 为了完成了一个高性能的 Java 聊天程序,在前面的文章中,尼恩已经再一次的进行了通讯协议的重新选择. 这就是:放弃了大家非常熟悉的json 格式,选择了性能更佳的 Protobuf协议. 在上一篇文章中,并且完成了Netty 和 Protobuf协议

Python标准库03 路径与文件 (os.path包, glob包)

作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 路径与文件的简介请参看Linux文件系统 os.path包 os.path包主要是处理路径字符串,比如说'/home/vamei/doc/file.txt',提取出有用信息. import os.path path = '/home/vamei/doc/file.txt' print(os.path.basename(path)) # 查询路径中包含的文件名 print(os.p

各类计算机毕业设计代做,包代包过!

代做,定做毕业设计,论文.毕业生网站设计,系统开发.包代包过 QQ:80072496

关于war包 jar包 ear包 及打包方法

关于war包 jar包 ear包 及打包方法 war包:是做好一个web应用后,通常是网站打成包部署到容器中 jar包:通常是开发的时候要引用的通用类,打成包便于存放管理. ear包:企业级应用 通常是EJB打成ear包 各种包的打法: 转: 兄弟,对java着迷吗,或者是为了自己的生计,不论怎样都欢迎你进入精彩java世界,welcome!可能你刚刚对每个人说:Hello World!也或者……ok!这已经足够了.那就让我们开始吧,开始这个魔幻世界的旅程: jar文件听说过吗,没有?或者陌生!

如何处理在反编译时,原包验证包名问题

最近在反编译时,修改包名,反编译回去时,遇到一个问题: 这样看来应该是原包对包名进行了验证,那么该如何处理呢? 首先可以直接去public.xml里面去找一下"The Application bundle is has been modified. Please build the app again." 看看是不是在资源里面有这个字符串. 在里面并没有指定的字符串. 那么只能说明这一串字符是直接写到了代码里,此时可以使用Submine Text的find in files来找一下: