所谓粘包问题主要还是C/S两端数据传输时  因为接收方不知道消息之间的界限,不知道一次性提取多少字节的数据所造成的
根本原因:
粘包是由TCP协议本身造成的,TCP为提高传输效率,发送方往往要收集到足够多的数据后才发送一个TCP段。若连续几次需要send的数据都很少,通常TCP会根据优化算法把这些数据合成一个TCP段后一次发送出去,这样接收方就收到了粘包数据。 解决方法: 1、自定义字典类型 的数据报头{文件名:a,文件的size:1090}计算出该报头的长度(len(字节)), 2、使用struct.pack('i',报头长度(一个数字))把一个数字压缩成固定的size 4个字节,发送给对端。 3、对端 struct.unpack(‘i’,recv(4))接收固定大小4个字节;这就是接收到了 报头的长度。 4.recv(报头长度)这就是发送过来的报头信息了


import struct
a='您好'
a=len(a.encode('utf-8')) #字节的长度=====这个数据有多大字节
# 1英文字母utf-8编码后=1字节
# #1中文字符 utf-8编码后=3个字节
#
a=struct.pack('i',a) #struct.pack把数字转换成 固定大小 4个字节的 字节
print(len(a)) #4个字节
print(struct.unpack('i',a)[0]) #struct.unpack[0] 把成自己解包会数字
服务端
# import socket
# import subprocess
# iphon=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #(建立一个socket对象)
# iphon.bind(('127.0.0.1',8080)) #绑定到 IP+端口上 成为唯一的socket
# iphon.listen(5) #设置连接池的个数
# print('starting........')
# while True: #连接循环
# conn,addr=iphon.accept() #等待电话连接
# print('电话线路是',conn)
# print('客户手机号:',addr)
# while True: #通信循环 发送和接收
# try:
# data=conn.recv(1024) #接受消息 最大从内存里接受1024MB数据
# print('客户端发来的消息是%s'%data)
# data=data.decode('utf-8') #从客户端发来的数据是经过编码的字节数据 所以需要解码 成Unicode
# res=subprocess.Popen( data, shell=True, stdout=subprocess.PIPE) #解码后传进subprocess.Popen去cmd执行
# data1 = res.stdout.read().decode('gbk') #cmd是gbk编码所以需要gbk解码
# print(data1) #打印解码后的结果
# data1=data1.encode('gbk') #编码
# conn.send(data1) #发送消息 #编码后再传输给客户端
# except Exception:
# break
# conn.close()
# iphon.close() import socket
import struct
import json
phon=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phon.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
phon.bind(("127.0.0.1",8090))
phon.listen(80) #
while True:
conn,addr=phon.accept()
while True:
try:
data=conn.recv(4) #接受4个字节的报头
data=struct.unpack('i',data)[0]
data1=conn.recv(data).decode('utf-8') #接受 字节类型的报头信息
#{"file_name": "\u4f60\u597d", "file_size": 6}
data1=json.loads(data1)
print(data1)
da=conn.recv(data1['file_size']).decode('utf-8') #接收真实数据
print(da) # print("接受到来自客户端发来的消息",data)
conn.send('sss'.encode('utf-8')) #发送接受的消息 给某一个客户端
except Exception:
break
conn.close()
phon.close()

  


客户端
import socket
import struct
import json
phon=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phon.connect(('127.0.0.1',8090)) #客户端的phon.connect正好对于服务端的phon1.accept()
while True: #循环通信
mes=input('---->: '.strip())
if not mes:
continue
mes = mes.encode('utf-8')
mes_len = len(mes)
head = {'file_name': mes.decode('utf-8'), 'file_size': mes_len}
head_json = json.dumps(head) # {"file_name": "a", "file_size": 1}
head_bytes = head_json.encode('utf-8')
head_bytes_len = len(head_bytes) #
struct1 = struct.pack('i',head_bytes_len)
send_=phon.send(struct1) #发送4个字节的 报头长度
data=phon.send(head_bytes) #发送报头
da=phon.send(mes) #发送真实数据 phon.close()

解决 TCP_socket 粘包问题的更多相关文章

  1. C#下利用封包、拆包原理解决Socket粘包、半包问题(新手篇)

    介于网络上充斥着大量的含糊其辞的Socket初级教程,扰乱着新手的学习方向,我来扼要的教一下新手应该怎么合理的处理Socket这个玩意儿. 一般来说,教你C#下Socket编程的老师,很少会教你如何解 ...

  2. 解决Socket粘包问题——C#代码

    解决Socket粘包问题——C#代码 前天晚上,曾经的一个同事问我socket发送消息如果太频繁接收方就会有消息重叠,因为当时在外面,没有多加思考 第一反应还以为是多线程导致的数据不同步导致的,让他加 ...

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

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

  4. Netty使用LineBasedFrameDecoder解决TCP粘包/拆包

    TCP粘包/拆包 TCP是个”流”协议,所谓流,就是没有界限的一串数据.TCP底层并不了解上层业务数据的具体含义,它会根据TCP缓冲区的实际情况进行包的划分,所以在业务上认为,一个完整的包可能会被TC ...

  5. 深入学习Netty(5)——Netty是如何解决TCP粘包/拆包问题的?

    前言 学习Netty避免不了要去了解TCP粘包/拆包问题,熟悉各个编解码器是如何解决TCP粘包/拆包问题的,同时需要知道TCP粘包/拆包问题是怎么产生的. 在此博文前,可以先学习了解前几篇博文: 深入 ...

  6. netty 解决TCP粘包与拆包问题(二)

    TCP以流的方式进行数据传输,上层应用协议为了对消息的区分,采用了以下几种方法. 1.消息固定长度 2.第一篇讲的回车换行符形式 3.以特殊字符作为消息结束符的形式 4.通过消息头中定义长度字段来标识 ...

  7. netty 解决TCP粘包与拆包问题(一)

    1.什么是TCP粘包与拆包 首先TCP是一个"流"协议,犹如河中水一样连成一片,没有严格的分界线.当我们在发送数据的时候就会出现多发送与少发送问题,也就是TCP粘包与拆包.得不到我 ...

  8. Netty解决TCP粘包/拆包问题 - 按行分隔字符串解码器

    服务端 package org.zln.netty.five.timer; import io.netty.bootstrap.ServerBootstrap; import io.netty.cha ...

  9. 1. Netty解决Tcp粘包拆包

    一. TCP粘包问题 实际发送的消息, 可能会被TCP拆分成很多数据包发送, 也可能把很多消息组合成一个数据包发送 粘包拆包发生的原因 (1) 应用程序一次写的字节大小超过socket发送缓冲区大小 ...

随机推荐

  1. Go 字典(Map)

    比较熟悉 Python 的对于字典肯定不会陌生,在 Go 中 map 就是 Python 中字典的概念,它的基本格式是 map[keyType]valueType .map 的读取和设置和 slice ...

  2. C语言 深入学习

    浮点数: x = Mx*2^Ex为一个规格化浮点数,Mx为x的尾数,Ex为x的阶码. 1e-6:表示1 * 10 ^ (-6). 编译时执行: sizeof是运算符(而非函数),在编译时执行,不会导致 ...

  3. mutect/mutsig/gistic官网汇总

    http://software.broadinstitute.org/software/cprg/

  4. 获取IP及判断IP是否在区间

    /// <summary> /// 获取客户端IP /// </summary> /// <returns></returns> public stat ...

  5. ThreadPoolExecutor最佳实践--如何选择线程数

    去年看过一篇<ThreadPoolExecutor详解>大致讲了ThreadPoolExecutor内部的代码实现. 总结一下,主要有以下四点: 当有任务提交的时候,会创建核心线程去执行任 ...

  6. 记录一次在centos下使用gmp的悲伤

    有个作业是需要在linux下做的,并且需要用到gmp这个 library : 我使用的是虚拟机centos7.很久没碰过linux了,忘得差不多了,一点点百度出来的 1. 首先检查是否已存在gmp库 ...

  7. 力扣(LeetCode) 66. 加一

    给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一. 最高位数字存放在数组的首位, 数组中每个元素只存储一个数字. 你可以假设除了整数 0 之外,这个整数不会以零开头. 示例 1: 输入 ...

  8. js 垃圾回收机制和引起内存泄漏的操作

    垃圾回收机制 JS中最常见的垃圾回收方式是标记清除. 工作原理:是当变量进入环境时,将这个变量标记为“进入环境”.当变量离开环境时,则将其标记为“离开环境”.标记“离开环境”的就回收内存. 工作流程: ...

  9. leecode第四题(寻找两个有序数组的中位数)

    题解: class Solution { public: double findMedianSortedArrays(vector<int>& nums1, vector<i ...

  10. SuperMap 二维地图和三维场景弹窗窗口大小控制

    注:此处所说的弹窗窗口,主要指的是那些弹窗窗口中嵌入iframe,包含信息页面的窗口大小控制. 1.首先来了解下 SuperMap 示例中的处理方案 二维的处理方式 //初始化Anchored类 po ...