所谓粘包问题主要还是C/S两端数据传输时  因为接收方不知道消息之间的界限,不知道一次性提取多少字节的数据所造成的
根本原因:
粘包是由TCP协议本身造成的,TCP为提高传输效率,发送方往往要收集到足够多的数据后才发送一个TCP段。若连续几次需要send的数据都很少,通常TCP会根据优化算法把这些数据合成一个TCP段后一次发送出去,这样接收方就收到了粘包数据。

解决方法:
1、自定义字典类型 的数据报头{xx:a,data_len:1090} 计算出该报头的长度(len(字节)),
2、使用struct.pack('i',报头长度(一个数字))把一个数字压缩成固定的size 4个字节,发送给对端。
3、对端 struct.unpack(‘i’,recv(4))接收固定大小4个字节;这就是接收到了 报头的长度。
4、recv(报头长度)这就是发送过来的报头信息了

1、Server实现
address = ('localhost', 9102)

# AF_INET = ipv4;  SOCK_STREAM:TCP
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#
s.bind(address)
# 监听
s.listen(5)while True:
print('----server wait')
conn, addr = s.accept() data_head = TCP_base.parse_head(conn)
data_len = data_head['data_len']
data = conn.recv(data_len)
print('--data----------', data) time.sleep(5) head_len, head_bytes = TCP_base.build_header('this is tet', data)
conn.send(head_len)
conn.send(head_bytes)
conn.sendall('pk finish, new is bad'.encode('utf-8')) conn.close()

TCP_Base:

负责每次数据的头部的信息的解析与拼接

def parse_head(conn):
head_len = conn.recv(4) # s1 head-len
head_len = struct.unpack('i', head_len)[0]
# print('--head-len-', head_len)
data_head = conn.recv(head_len).decode('utf-8')
# print('--headinfo------', data_head)
data_head = json.loads(data_head)
# print('--headinfo-json-', data_head)
return data_head
def build_header(id, data):
data_len = len(data)
head_info = {'id': id, 'data_len': data_len}
head_json = json.dumps(head_info)
head_bytes = head_json.encode('utf-8')
head_bytes_len = len(head_bytes) head_len = struct.pack('i', head_bytes_len) return head_len, head_bytes

2、Client实现

self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 1 connect
self.s.connect(self.ip_port)
# 2 require send data
# self.s.sendall(cmd.encode(self.utf_8))
head_len, head_info = TCP_base.build_header(cmd, data)
self.s.send(head_len) # send head_len 4 Bit
self.s.send(head_info) # send head
self.s.sendall(data.encode(self.utf_8)) #send datas # 3 recv data
# data = self.s.recv(1024).decode(self.utf_8)
data_head = TCP_base.parse_head(self.s)
data_len = data_head['data_len']
data = self.s.recv(data_len)
print('--data----------', data)
# print(data)
# 4 close
self.s.close()


socket(TCP-粘包)通讯之Python实现的更多相关文章

  1. Socket/TCP粘包、多包和少包, 断包

    转发: https://blog.csdn.net/pi9nc/article/details/17165171 为什么TCP 会粘包 前几天,调试mina的TCP通信, 第一个协议包解析正常,第二个 ...

  2. UNIX网络编程——Socket/TCP粘包、多包和少包, 断包

    为什么TCP 会粘包 前几天,调试mina的TCP通信, 第一个协议包解析正常,第二个数据包不完整.为什么会这样吗,我们用mina这样通信框架,还会出现这种问题? TCP(transport cont ...

  3. TCP粘包问题分析和解决(全)

    TCP通信粘包问题分析和解决(全) 在socket网络程序中,TCP和UDP分别是面向连接和非面向连接的.因此TCP的socket编程,收发两端(客户端和服务器端)都要有成对的socket,因此,发送 ...

  4. 【转载】TCP粘包问题分析和解决(全)

    TCP通信粘包问题分析和解决(全) 在socket网络程序中,TCP和UDP分别是面向连接和非面向连接的.因此TCP的socket编程,收发两端(客户端和服务器端)都要有成对的socket,因此,发送 ...

  5. TCP 粘包及其解决方案(zz)

    首先,我们回顾一下 TCP 和 UDP 的头部信息: 具体说明看:http://www.cnblogs.com/aomi/p/7776582.html 我们知道,TCP 和 UDP 是 TCP/IP ...

  6. 【Python】TCP Socket的粘包和分包的处理

    Reference: http://blog.csdn.net/yannanxiu/article/details/52096465 概述 在进行TCP Socket开发时,都需要处理数据包粘包和分包 ...

  7. python套接字解决tcp粘包问题

    python套接字解决tcp粘包问题 目录 什么是粘包 演示粘包现象 解决粘包 实际应用 什么是粘包 首先只有tcp有粘包现象,udp没有粘包 socket收发消息的原理 发送端可以是一K一K地发送数 ...

  8. Socket编程(4)TCP粘包问题及解决方案

    ① TCP是个流协议,它存在粘包问题 TCP是一个基于字节流的传输服务,"流"意味着TCP所传输的数据是没有边界的.这不同于UDP提供基于消息的传输服务,其传输的数据是有边界的.T ...

  9. Socket编程实践(5) --TCP粘包问题与解决

    TCP粘包问题 由于TCP协议是基于字节流且无边界的传输协议, 因此很有可能产生粘包问题, 问题描述如下 对于Host A 发送的M1与M2两个各10K的数据块, Host B 接收数据的方式不确定, ...

  10. Python全栈-网络编程-TCP粘包

    一.什么是TCP粘包 C/S架构下,接收方不知道每个消息的发送间隙.也不知道每次应该提取多少个字节的数据,与此同时,TCP是面向连接的,面向流的,收发两端都要有,因此发送端为了将多个发往接收端的数据包 ...

随机推荐

  1. Eclipse 新建jsp文件报错问题

    今天在web工程中新建一个index.jsp文件时,发现会报错,记录一下解决办法. 原因:缺少servlet-api.jar包 所以我们先去下载一个jar包,将它引入我们的工程中,即可. 工程右键-& ...

  2. 链表倒数第k个节点

    1.一种较笨的办法是先将链表元素入栈,然后出栈找到倒数第k个节点值,再拿着值遍历链表去找到对于节点. 时间复杂度:O(n) (3n 遍历-出栈-遍历) 空间复杂度:O(n) (一个栈) 2.快慢指针, ...

  3. [20190418]exclusive latch spin count.txt

    [20190418]exclusive latch spin count.txt--//昨天测试"process allocation" latch,主要这个latch与其它拴锁s ...

  4. centos7新增硬盘

    centos7新增硬盘 步骤:分区---格式化---挂载(配置开机自动挂载) 1.分区 fdisk -l 查看硬盘信息确认新硬盘的名称(以/dev/sdb为例) fdisk /dev/sdb  管理硬 ...

  5. JS直接调用C#后台方法(ajax调用)

    1. 先手动引用DLL或者通过NuGet查找引用,这里提供一个AjaxPro.2.dll的下载: 2. 之后的的过程不想写了,网上都大同小异的,直接参考以前大佬写的: AjaxPro2完整入门教程 总 ...

  6. SQL Server数据库————模糊查询和聚合函数

    ***********模糊查询*********/ 关键字: like (!!!!字符串类型) in (,,)  匹配()内的某个具体值(括号里可以写多个值) between... and.. 在某两 ...

  7. php 7.1 新特性解析

    php 7.1 新特性解析 返回值和传入参数可以指定为 null <?php function testReturn(): ?string { return 'elePHPant'; } var ...

  8. 转载:教你分分钟搞定Docker私有仓库Registry

    一.什么是Docker私有仓库Registry 官方的Docker hub是一个用于管理公共镜像的好地方,我们可以在上面找到我们想要的镜像,也可以把我们自己的镜像推送上去.但是,有时候我们的服务器无法 ...

  9. 使用栈实现队列(1)(Java)

    class MyQueue { private Stack s1; private Stack s2; public MyQueue(int size) { this.s1 = new Stack(s ...

  10. 正则表达式和re模块

    目录 re的元字符 字符集[ ] 转义符 分组 ( ) |符号 re下的常用方法 分组 re的元字符 import re ret = re.findall("e..a", &quo ...