缓冲区:暂时存放传输数据的,防止你的程序在发送数据的时候卡主,提高代码运行效率

    输入缓冲区:recv

    输出缓冲区:send

    缓冲区有长度限制

MTU最大传输单元,网络层限制是1500B,每次发送数据的时候最好不要超过这个数

粘包

  粘包现象:

  1.连续发送小的数据,间隔时间很短,有可能一次就接受欧到了这几个连续的情节在一起的小数据,

  原因:未来提高tcp传输效率,内部提供了一个叫做Nagel算法,他的意思就是未来避免你连续发送小数据.

  2.当你一次接收的数据长度小于你一次发送的数据长度,那么一次接收完剩下的数据会在下一次接收数据的时候一起接收

  原因:面向流的传输

  粘包的根本原因:

    两端互相不知道对方发送数据的长度

  针对上面的原因有两种解决粘包的方法

  

    1在发送数据前,先发送数据的长度,name接收根据的长度来进行接收数据

 服务端:

    

import socketimport subprocess

server = socket.socket()ip_port = ('192.168.15.113',8001)server.bind(ip_port)server.listen()conn,addr = server.accept()while 1:    #来自客户端的指令    print('等待接受信息。。。')    from_client_cmd = conn.recv(1024).decode('utf-8')    print(from_client_cmd)    sub_obj = subprocess.Popen(        from_client_cmd, #客户端的指令        shell=True,        stdout=subprocess.PIPE,        stderr=subprocess.PIPE,    )

    #接受到的返回信息是bytes类型的,并且windows系统的默认编码为gbk    server_cmd_msg = sub_obj.stdout.read()    # server_cmd_err = sub_obj.stderr.read().decode('gbk')    cmd_msg_len = str(len(server_cmd_msg))    print('指令返回的正确信息的长度>>>',cmd_msg_len)    # print('指令返回的正确信息>>>',server_cmd_msg)    # print('指令返回的错误信息...',server_cmd_err)

    conn.send(cmd_msg_len.encode('gbk'))

    from_client_ack = conn.recv(1024).decode('utf-8')    print('from_client_ack',from_client_ack)    if from_client_ack == 'ok':

        conn.send(server_cmd_msg)    else:        continue

    

 客户端:

    

import socketclient = socket.socket()server_ip_port = ('192.168.15.113',8001)client.connect(server_ip_port)while 1:    msg = input('请输入要执行的指令>>>')    client.send(msg.encode('utf-8'))    #先接收服务端要发送给我的信息的长度    from_server_msglen = int(client.recv(1024).decode('gbk'))    print('..........',from_server_msglen)    #给服务端回应一个收到了你的信息长度的确认信息    client.send('ok'.encode('utf-8'))

    #拿到信息长度后,将信息长度作为参数给了recv,recv就按照这个长度大小来接受服务端后面要给我发送的数据    from_server_stdout = client.recv(from_server_msglen).decode('gbk')

    print('收到的正确信息:', from_server_stdout)

    # from_server_error = client.recv(1024).decode('utf-8')    # print('收到的错误信息:',from_server_error)

2. 把要发送的数据打成包的形式直接传输

服务端:

  

import socketimport subprocessimport struct

server = socket.socket()ip_port = ('192.168.15.113',8001)server.bind(ip_port)server.listen()conn,addr = server.accept()while 1:    #来自客户端的指令    print('等待接受信息。。。')    from_client_cmd = conn.recv(1024).decode('utf-8')    print(from_client_cmd)    #通过subprocess模块执行服务端的系统指令,并且拿到指令执行结果    sub_obj = subprocess.Popen(        from_client_cmd, #客户端的指令        shell=True,        stdout=subprocess.PIPE, #标准输出:正确指令的执行结果在这里        stderr=subprocess.PIPE, #标准错误输出:错误指令的执行结果在这里    )    #接受到的返回信息是bytes类型的,并且windows系统的默认编码为gbk    server_cmd_msg = sub_obj.stdout.read()    # server_cmd_err = sub_obj.stderr.read().decode('gbk')    #首先计算出你将要发送的数据的长度    cmd_msg_len = len(server_cmd_msg)    #先对数据长度进行打包,打包成4个字节的数据,目的是为了和你将要发送的数据拼在一起,就好我们自定制了一个消息头    msg_len_stru = struct.pack('i',cmd_msg_len)    conn.send(msg_len_stru) #首先发送打包成功后的那4个字节的数据    conn.sendall(server_cmd_msg) #循环send数据,直到数据全部发送成功

  

客户端: 

    

import socketimport structclient = socket.socket()server_ip_port = ('192.168.15.113',8001)client.connect(server_ip_port)while 1:    msg = input('请输入要执行的指令>>>')    client.send(msg.encode('utf-8'))    #先接收服务端要发送给我的信息的长度,前4个字节,固定的    from_server_msglen = client.recv(4)    unpack_len_msg = struct.unpack('i',from_server_msglen)[0]    #接收数据长度统计,和服务端发给我的数据长度作比较,来确定跳出循环的条件    recv_msg_len = 0    #统计拼接接收到的数据,注意:这个不是统计长度    all_msg = b''    while recv_msg_len < unpack_len_msg:        every_recv_data = client.recv(1024)        #将每次接收的数据进行拼接和统计        all_msg += every_recv_data        #对每次接收到的数据的长度进行累加        recv_msg_len += len(every_recv_data)

    print(all_msg.decode('gbk'))
  

转载于:https://www.cnblogs.com/lilei1996/p/9811694.html

缓冲区,粘包,解决粘包的方法,相关推荐

  1. TCP利用封包和解包解决“粘包”问题

    本文参考自徐晓鑫<后台开发>,给出一个可实际应用的demo,该demo核心在于封包和解包的思想,以及自定义发送.接收数据. 一.TCP粘包现象 what? TCP是个"流&quo ...

  2. Python之网络编程(粘包、粘包解决方案)

    文章目录 tcp粘包 第一种粘包 第二种粘包 udp粘包 解决粘包现象 粘包现象是指发送方发送的若干数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾.粘包现象只会在tcp ...

  3. 关于Socket粘包、半包问题的解决方法

    背景 在 Java 语言中,传统的 Socket 编程分为两种实现方式,这两种实现方式也对应着两种不同的传输层协议:TCP 协议和 UDP 协议. 但作为互联网中最常用的传输层协议 TCP,在使用时却 ...

  4. mina 粘包、多包和少包的解决方法

    转载自:http://freemart.iteye.com/blog/836654 使用过 mina 的同学应该都遇到到过,在解码时少包.多包的问题,查阅了很多资料还是迷迷糊糊的,经过不懈努力,终于解 ...

  5. Android 串口开发——粘包解决方法,定时查询心跳数据,解析心跳数据。——持续更新中

    粘包解决方法 方法1 getXOR--是校验方法 /*** 最小数据包的长度(除开数据的N个字节)* 帧头 保留字节 协议控制字 地址字段 命令长度 命令码 命令数据 校验和* 2字节 3字节 1字节 ...

  6. 【Netty】Netty解决粘包和拆包问题的四种方案

    在RPC框架中,粘包和拆包问题是必须解决一个问题,因为RPC框架中,各个微服务相互之间都是维系了一个TCP长连接,比如dubbo就是一个全双工的长连接.由于微服务往对方发送信息的时候,所有的请求都是使 ...

  7. 10.python网络编程(解决粘包问题 part 2)

    一.什么时候会产生粘包现象. 只有在使用tcp协议的情况下才会产生粘包现象!udp协议永远不会! 发送端可以1k1k的把数据发送出去,接收端,可以2k2k的的去接收数据,一次可能会接收3k,也有可能1 ...

  8. Netty 解决粘包和拆包问题的四种方案

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 来源 | https://my.oschina.net/ ...

  9. Netty解决粘包和拆包问题的四种方案

    在RPC框架中,粘包和拆包问题是必须解决一个问题,因为RPC框架中,各个微服务相互之间都是维系了一个TCP长连接,比如dubbo就是一个全双工的长连接.由于微服务往对方发送信息的时候,所有的请求都是使 ...

最新文章

  1. C# Revert 单词反转字符串!『测试通过』
  2. kohana中的路由规则
  3. pg数据库与MySQL的count函数_postgresql数据库连接数和状态查询操作
  4. 计算机网络技术及应用 课程 英语,计算机网络应用—现代英语课堂中的第三种语言...
  5. Youtube深度学习推荐系统
  6. PHP无限极分类原理
  7. python 测试框架
  8. ubuntu系统备份和还原_如何使用Aptik在Ubuntu中备份和还原您的应用程序和PPA
  9. Spring-web源码解析之Filter-AbstractRequestLoggingFilter
  10. burp 代理的时候无法访问https网站
  11. mybatis 带分号批量sql_请查收,32 道 MyBatis 的高频面试题已答完
  12. php 不支持curl 的解决方案
  13. 服务器传输文件损坏,使用ftplib将文件传输到FTP服务器后,文件已损坏
  14. JS对数据进行判空操作
  15. mac地址是由多少个bit组成_IPv6系列-详解自动分配IPv6地址
  16. 一个有趣的Java编译问题
  17. GalGame汉化教程(一)——Ollydbg修改编码和字体
  18. PMBOK第六版学习笔记
  19. 通用码头计算机管理系统,智慧港口码头货物管理解决方案_华测导航-华测导航...
  20. Word文档标题自动增加序号

热门文章

  1. 读取遥感图像中遇到的问题集锦
  2. 去除UINavigationBar的下边框
  3. c++ 1:非MFC工程使用MFC库时的问题及解决办法(如果要用CString或者提示windows头文件重复包含)...
  4. 利用Cache防止同一帐号重复登录
  5. [转]WinForm--使用C#制做进程监视器
  6. 中年程序员对核心竞争力“不可替代”的重新认识
  7. VS2010与Windows7共舞:对库进行编程
  8. Reservoir Sampling 蓄水池采样算法
  9. 装NOILinux的奇妙经历
  10. selenium webdriver 实现Canvas画布自动化测试