socket(TCP-粘包)通讯之Python实现
所谓粘包问题主要还是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实现的更多相关文章
- Socket/TCP粘包、多包和少包, 断包
转发: https://blog.csdn.net/pi9nc/article/details/17165171 为什么TCP 会粘包 前几天,调试mina的TCP通信, 第一个协议包解析正常,第二个 ...
- UNIX网络编程——Socket/TCP粘包、多包和少包, 断包
为什么TCP 会粘包 前几天,调试mina的TCP通信, 第一个协议包解析正常,第二个数据包不完整.为什么会这样吗,我们用mina这样通信框架,还会出现这种问题? TCP(transport cont ...
- TCP粘包问题分析和解决(全)
TCP通信粘包问题分析和解决(全) 在socket网络程序中,TCP和UDP分别是面向连接和非面向连接的.因此TCP的socket编程,收发两端(客户端和服务器端)都要有成对的socket,因此,发送 ...
- 【转载】TCP粘包问题分析和解决(全)
TCP通信粘包问题分析和解决(全) 在socket网络程序中,TCP和UDP分别是面向连接和非面向连接的.因此TCP的socket编程,收发两端(客户端和服务器端)都要有成对的socket,因此,发送 ...
- TCP 粘包及其解决方案(zz)
首先,我们回顾一下 TCP 和 UDP 的头部信息: 具体说明看:http://www.cnblogs.com/aomi/p/7776582.html 我们知道,TCP 和 UDP 是 TCP/IP ...
- 【Python】TCP Socket的粘包和分包的处理
Reference: http://blog.csdn.net/yannanxiu/article/details/52096465 概述 在进行TCP Socket开发时,都需要处理数据包粘包和分包 ...
- python套接字解决tcp粘包问题
python套接字解决tcp粘包问题 目录 什么是粘包 演示粘包现象 解决粘包 实际应用 什么是粘包 首先只有tcp有粘包现象,udp没有粘包 socket收发消息的原理 发送端可以是一K一K地发送数 ...
- Socket编程(4)TCP粘包问题及解决方案
① TCP是个流协议,它存在粘包问题 TCP是一个基于字节流的传输服务,"流"意味着TCP所传输的数据是没有边界的.这不同于UDP提供基于消息的传输服务,其传输的数据是有边界的.T ...
- Socket编程实践(5) --TCP粘包问题与解决
TCP粘包问题 由于TCP协议是基于字节流且无边界的传输协议, 因此很有可能产生粘包问题, 问题描述如下 对于Host A 发送的M1与M2两个各10K的数据块, Host B 接收数据的方式不确定, ...
- Python全栈-网络编程-TCP粘包
一.什么是TCP粘包 C/S架构下,接收方不知道每个消息的发送间隙.也不知道每次应该提取多少个字节的数据,与此同时,TCP是面向连接的,面向流的,收发两端都要有,因此发送端为了将多个发往接收端的数据包 ...
随机推荐
- Eclipse 新建jsp文件报错问题
今天在web工程中新建一个index.jsp文件时,发现会报错,记录一下解决办法. 原因:缺少servlet-api.jar包 所以我们先去下载一个jar包,将它引入我们的工程中,即可. 工程右键-& ...
- 链表倒数第k个节点
1.一种较笨的办法是先将链表元素入栈,然后出栈找到倒数第k个节点值,再拿着值遍历链表去找到对于节点. 时间复杂度:O(n) (3n 遍历-出栈-遍历) 空间复杂度:O(n) (一个栈) 2.快慢指针, ...
- [20190418]exclusive latch spin count.txt
[20190418]exclusive latch spin count.txt--//昨天测试"process allocation" latch,主要这个latch与其它拴锁s ...
- centos7新增硬盘
centos7新增硬盘 步骤:分区---格式化---挂载(配置开机自动挂载) 1.分区 fdisk -l 查看硬盘信息确认新硬盘的名称(以/dev/sdb为例) fdisk /dev/sdb 管理硬 ...
- JS直接调用C#后台方法(ajax调用)
1. 先手动引用DLL或者通过NuGet查找引用,这里提供一个AjaxPro.2.dll的下载: 2. 之后的的过程不想写了,网上都大同小异的,直接参考以前大佬写的: AjaxPro2完整入门教程 总 ...
- SQL Server数据库————模糊查询和聚合函数
***********模糊查询*********/ 关键字: like (!!!!字符串类型) in (,,) 匹配()内的某个具体值(括号里可以写多个值) between... and.. 在某两 ...
- php 7.1 新特性解析
php 7.1 新特性解析 返回值和传入参数可以指定为 null <?php function testReturn(): ?string { return 'elePHPant'; } var ...
- 转载:教你分分钟搞定Docker私有仓库Registry
一.什么是Docker私有仓库Registry 官方的Docker hub是一个用于管理公共镜像的好地方,我们可以在上面找到我们想要的镜像,也可以把我们自己的镜像推送上去.但是,有时候我们的服务器无法 ...
- 使用栈实现队列(1)(Java)
class MyQueue { private Stack s1; private Stack s2; public MyQueue(int size) { this.s1 = new Stack(s ...
- 正则表达式和re模块
目录 re的元字符 字符集[ ] 转义符 分组 ( ) |符号 re下的常用方法 分组 re的元字符 import re ret = re.findall("e..a", &quo ...