1.粘包现象
TCP粘包是指发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾。
 
粘包出现原因
使用了优化方法(Nagle算法),将多次间隔较小、数据量小的数据,合并成一个大的数据块,然后进行封包。
简单得说,在流传输中出现,UDP不会出现粘包,因为它有消息边界
1发送端需要等缓冲区满才发送出去,造成粘包
2接收方不及时接收缓冲区的包,造成多个包接收
 
解决方法
接收方创建一预处理线程,对接收到的数据包进行预处理,将粘连的包分开。
 
TCP无保护消息边界的解决
针对这个问题,一般有3种解决方案:
(1)发送固定长度的消息
(2)把消息的尺寸与消息一块发送
(3)使用特殊标记来区分消息间隔
 
2.struct模块
该模块可以把一个类型,如数字,转成固定长度的bytes
 
可以转的类型:

 用法:

import struct

ret = struct.pack('i',23333)    #i表示int类型,把23333转成固定长度的bytes类型

struct.pack('i',ret)    #把bytes转回int
3.例子
#以远程执行命令为例讲解决方法
#先发送传输的大小
服务端:
import socket
import struct
sk = socket.socket()
s = ('127.0.0.1', 8081)
sk.bind(s)
sk.listen(2)
conn, addr = sk.accept()
while 1:
cmd = input('[cmd] #')
if cmd == 'q':
break
conn.send(cmd.encode('utf-8'))
lens = conn.recv(4) #接收包长度
lens = struct.unpack('i',lens)[0]
info = conn.recv(lens)
print(info.decode('gbk')) 客户端:
import socket
import subprocess
import struct
sk = socket.socket()
sk.connect(('127.0.0.1',8081))
while 1:
cmd = sk.recv(1024).decode('gbk')
res = subprocess.Popen(cmd,shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
std = res.stdout.read()+res.stderr.read()
lens = len(std)
lens = struct.pack('i', lens) #把长度转成4个字节的bytes
sk.send(lens)
sk.send(std)
 

python 网络编程 粘包问题的更多相关文章

  1. python网络编程--粘包解决方案 和 subprocess模块

    1.缓冲区:作用:将程序和网络解耦分为输入缓冲区, 输出缓冲区 每个 socket 被创建后,都会分配两个缓冲区,输入缓冲区和输出缓冲区.write()/send() 并不立即向网络中传输数据,而是先 ...

  2. python 网络编程粘包解决方案2 + ftp上传 + socketserver

    一.struct 神奇的打包工具 struct 代码: import struct num = 156 #将int类型的数据打包成4个字节的数据 num_stru = struct.pack('i', ...

  3. python 网络编程---粘包

    一.什么是粘包?(只有在TCP中有粘包现象,在UDP中永远不会粘包) 黏包不一定会发生. 如果发生 了:1.可能是在客户端已经粘了 2.客户端没有粘,可能是在服务端粘了. 所谓的粘包问题:主要是是因为 ...

  4. 网络编程----粘包以及粘包问题的解决、FTP上传

    一.粘包现象 让我们基于tcp先制作一个远程执行命令的程序(1:执行错误命令 2:执行ls 3:执行ifconfig) 注意注意: res=subprocess.Popen(cmd.decode('u ...

  5. Python网络编程04 /recv工作原理、展示收发问题、粘包现象

    Python网络编程04 /recv工作原理.展示收发问题.粘包现象 目录 Python网络编程04 /recv工作原理.展示收发问题.粘包现象 1. recv工作原理 2. 展示收发问题示例 发多次 ...

  6. Python学习笔记【第十四篇】:Python网络编程二黏包问题、socketserver、验证合法性

    TCP/IP网络通讯粘包问题 案例:模拟执行shell命令,服务器返回相应的类容.发送指令的客户端容错率暂无考虑,按照正确的指令发送即可. 服务端代码 # -*- coding: utf- -*- # ...

  7. Python 网络编程(二)

    Python 网络编程 上一篇博客介绍了socket的基本概念以及实现了简单的TCP和UDP的客户端.服务器程序,本篇博客主要对socket编程进行更深入的讲解 一.简化版ssh实现 这是一个极其简单 ...

  8. python 网络编程(Socket)

    # from wsgiref.simple_server import make_server## def RunServer(environ,start_response):# start_resp ...

  9. 28、Python网络编程

    一.基于TCP协议的socket套接字编程 1.套接字工作流程 先从服务器端说起.服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客 ...

随机推荐

  1. 实现路由器自动登录校园网(edu)

    准备工作: (1)一个可以刷openwrt固件的路由器,如大多人使用的crazybox版本的路由. (2)一个可用的edu账号. (3)一个浏览器(firfox,chrome) 下面开始: 一:刷op ...

  2. C# 常用字符串加密解密方法

    using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Sec ...

  3. PHP面向对象(二)

    7 多态 多态: 多种形态 多态分俩种: 方法重写和方法加载 7.1 方法重写 子类重写了父类的同名的方法 <?php class Person{ public function show(){ ...

  4. php中的form表单

    表单处理 表单的概念在生活中很常见,就像是问卷调查表一样,别人先把问卷发给你,你照着问卷的要求填写,完事过后再将填完的问卷发给别人,从而达到一个将别人需要的信息传递给别人的一种方式. 传统的网页大多数 ...

  5. tp3.1 白板不报错

    今天有碰上了这种情况, 一般记忆力好把刚才改动的地方恢复一下就好了,但是今天特殊原因编辑器不小心关了,也不知道把那里改坏了,一通乱找,也找不到.汗! 没办法,提交代码几面,用git看下改变的地方,是c ...

  6. 【CodeForces 271D】Good Substrings

    [链接] 我是链接,点我呀:) [题意] [题解] 字典树 我们可以两重循环(i,j) 来枚举所有的子串 即i=1,j=1,2,3... i=2,j = 2,3,4,.. 于是我们在i变化的时候(就是 ...

  7. Docker学习总结(14)——从代码到上线, 云端Docker化持续交付实践

    2016云栖大会·北京峰会于8月9号在国家会议中心拉开帷幕,在云栖社区开发者技术专场中,来自阿里云技术专家罗晶(瑶靖)为在场的听众带来<从代码到上线,云端Docker化持续交付实践>精彩分 ...

  8. Java - 经常使用函数Random函数

    http://blog.csdn.net/pipisorry/article/details/44411541 Random()函数生成随机数 java.util.Random 在Java的API帮助 ...

  9. POJ1390 Blocks 【动态规划】

    Blocks Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 4173   Accepted: 1661 Descriptio ...

  10. hdoj--5532--Almost Sorted Array(正反LIS)

    Almost Sorted Array Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Ot ...