TCP协议下的粘包问题

TCP协议下的粘包问题

  • 粘包问题出现在TCP协议下,在UDP协议下不会出现粘包的问题。
  • 粘包问题出现的原因:

    应用层被成为应用元,操作系统被被称为系统元

    • 合包机制:在TCP协议下有一个合包机制,当应用层传输过来数据后,如果数据较小,并且连续多次传输,此时nagle算法会对把多个数据进行
      打包,统一发送给接收方,

      • 好处是:减少了网络资源的消耗,接收方只需要给发送方回传一份回执即可,如果不进行合包操作,每发送一条数据,接收方就需要回一份回执,会大量消耗网络资源。
      • 弊端是:由于TCP协议下字节流没有明确的边界,很可能出现多条数据打包后到接收方接收的是一条数据,并没有拆分,这是粘包的一种情况。
      
      '''client.py'''
      import socket
      sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
      sk.connect(('172.16.12.164', 8085))
      msg1 = sk.recv(1024)
      msg2 = sk.recv(1024)
      print(msg1)
      print(msg2)
      
      '''server.py'''
      import socket
      sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
      sk.bind(('172.16.12.164', 8085))
      # 申请网络资源
      sk.listen()
      conn, addr = sk.accept()
      conn.send(b'hello')
      conn.send(b'world')
      
      '''输出结果'''
      b'helloworld'
      b''
      # 出现了粘包现象,两次输入的结果放在了一次输出,第二次输出为空
    • 拆包机制:在TCP协议中除了合包机制外,还有拆包机制。当传输的数据过大,已经超过网卡的MTU限制的时候,TCP协议会自动的把大的文件拆分成多个小于MTU的包分别进行发送。
      • 好处是:这样的话像视频、歌曲等大的文件就可以在TCP协议下进行阐述,不会对数据的大小有进行限制。
      • 弊端是:当传输两个被拆分成多个的大的数据时,前一个数据的最后一块可能和后一个数据的第一块产生粘包问题。例如:第一个文件5000byte,后一个文件2500byte,正常情况下MTU的值为1500。那么第一个数据会被拆分为1500、1500、1500、500,第一个数据的最后一部分不够1500,操作系统的缓存机制起作用了,第二个大的数据传过来的时候先拆分出1000,加上第一个数据的500,组成1500,剩下的再进行拆分,传输过去的时候就发生了前一个数据的最后部分和后一个数据的开始部分发生了粘包的现象。

原文地址:https://www.cnblogs.com/ddzc/p/12381030.html

时间: 2024-08-28 09:15:49

TCP协议下的粘包问题的相关文章

golang中解决tcp传输中的粘包问题

"-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> golang中解决tcp传输中的粘包问题 - Programmer小卫 - 博客频道 - CSDN.NET Programmer小卫 故不积跬步,无以至千里.不积小流,无以成江海. 目录视图 摘要视图 订阅 [活动]2017 CSDN博客专栏评选 &nbsp [5月书

TCP协议下的服务端并发,GIL全局解释器锁,死锁,信号量,event事件,线程q

TCP协议下的服务端并发,GIL全局解释器锁,死锁,信号量,event事件,线程q 一.TCP协议下的服务端并发 ''' 将不同的功能尽量拆分成不同的函数,拆分出来的功能可以被多个地方使用 TCP服务端实现并发 1.将连接循环和通信循环拆分成不同的函数 2.将通信循环做成多线程 ''' # 服务端 import socket from threading import Thread ''' 服务端 要有固定的IP和PORT 24小时不间断提供服务 能够支持并发 ''' server = sock

基于tcp协议下粘包现象和解决方案

一.缓冲区 每个 socket 被创建后,都会分配两个缓冲区,输入缓冲区和输出缓冲区.write()/send() 并不立即向网络中传输数据,而是先将数据写入缓冲区中,再由TCP协议将数据从缓冲区发送到目标机器.一旦将数据写入到缓冲区,函数就可以成功返回,不管它们有没有到达目标机器,也不管它们何时被发送到网络,这些都是TCP协议负责的事情.TCP协议独立于 write()/send() 函数,数据有可能刚被写入缓冲区就发送到网络,也可能在缓冲区中不断积压,多次写入的数据被一次性发送到网络,这取决

tcp协议下粘包问题的产生及解决方案

1.粘包产生原因: (1)TCP为提高传输效率,发送方往往要收集到足够多的数据后才发送一个TCP段.若连续几次需要send的数据都很少,通常TCP会根据优化算法(Nagle)把这些数据合成一个TCP段后一次发送出去,这样接收方就收到了粘包数据: (2)接收方不知道消息之间的界限,不知道一次性提取多少字节的数据:接收时有字节的限制,如果超过这个限制没有接收完的会留在 操作系统缓存,下次再执行命令获取结果时,优先收取上次命令结果残留的信息: 注:UDP是无连接的,面向消息的,提供高效率服务.不会使用

TCP协议下Socket接收比较慢点原因

在做一个游戏,发现阻塞和异步方式接受服务端的包都很反应很慢(不是网速问题),本机访问本机没这个问题,局域网有感觉200ms左右的延迟,部分机型感觉明显,部分不明显.找了很多资料,查到下面的文章,总算明白了. https://support.microsoft.com/zh-cn/kb/214397 设计问题-通过使用 Winsock TCP 发送较小的数据段  电子邮件  打印 重要说明:本文是由 Microsoft 机器翻译软件进行的翻译并可能由 Microsoft 社区通过社区翻译机构(

tcp套接字粘包解决办法

粘包只会出现在tcp,udp传输不会产生粘包现象.解决粘包的原理就是服务器预先向客户端发送客户端即将获取文件的大小. 第一版解决方案: 服务器: 1 # Author : Kelvin 2 # Date : 2019/2/2 17:38 3 from socket import * 4 import subprocess 5 6 ip_conf = ("127.0.0.1", 8888) 7 buffer_capacity = 1024 8 tcp_server = socket(AF

基于TCP协议下的socket编程

socket: TCP/IP协议中一个端口号和一个IP地址绑定在一起就生成一个socket就表示了网络中唯一的一个进程,它是全双工的工作方式. 基于TCP的socket编程 函数的使用: 1.socket()         #include <sys/types.h>          /* See NOTES */        #include <sys/socket.h>        int socket(int domain, int type, int protoco

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

一.什么时候会产生粘包现象. 只有在使用tcp协议的情况下才会产生粘包现象!udp协议永远不会! 发送端可以1k1k的把数据发送出去,接收端,可以2k2k的的去接收数据,一次可能会接收3k,也有可能1次接收6k. TCP协议是面向流的协议,这也是容易出现粘包问题的原因.而UDP是面向消息的协议,每个UDP段都是一条消息,应用程序必须以消息为单位提取数据,不能一次提取任意字节的数据,这一点和TCP是很不同的.怎样定义消息呢?可以认为对方一次性write/send的数据为一个消息,需要明白的是当对方

python学习_day30_基于tcp协议的粘包现象

1.基于远程执行命令的程序 需用到subprocess模块 服务端: #1.执行客户端发送的指令 import socket import subprocess phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) phone.bind(('127.0.0.1',8090)) phone.listen(5) while True: conn,addr=phone.accept() print('IP:%s PORT:%s' %(addr[0