tcp的粘包现象与解决方案】的更多相关文章

一.TCP协议 粘包现象 和解决方案 黏包现象让我们基于tcp先制作一个远程执行命令的程序(命令ls -l ; lllllll ; pwd)执行远程命令的模块 需要用到模块subprocess subprocess通过子进程来执行外部指令,并通过input/output/error管道,获取子进程的执行的返回信息. import os import subprocess ret = os.popen('dir').read() print(ret) print('*'*50) ret = sub…
粘包现象: 粘包1:连续的小包,会被优化机制给合并 粘包2:服务端一次性无法完全就收完客户端发送的数据,第二再次接收的时候,会接收到第一次遗留的内容 模拟一个粘包现象 服务端 import socket server = socket.socket(type=socket.SOCK_STREAM) ip_port = ('127.0.0.1',8080) server.bind(ip_port) server.listen() conn, addr = server.accept() # 粘包1…
一.缓冲区 每个 socket 被创建后,都会分配两个缓冲区,输入缓冲区和输出缓冲区.write()/send() 并不立即向网络中传输数据,而是先将数据写入缓冲区中,再由TCP协议将数据从缓冲区发送到目标机器.一旦将数据写入到缓冲区,函数就可以成功返回,不管它们有没有到达目标机器,也不管它们何时被发送到网络,这些都是TCP协议负责的事情.TCP协议独立于 write()/send() 函数,数据有可能刚被写入缓冲区就发送到网络,也可能在缓冲区中不断积压,多次写入的数据被一次性发送到网络,这取决…
看面经时,看到有面试官问TCP的粘包问题.想起来研一做购物车处理数据更新时遇到粘包问题,就总结一下吧. 1 什么是粘包现象 TCP粘包是指发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾. 2 为什么出现粘包现象 (1)发送方原因 我们知道,TCP默认会使用Nagle算法.而Nagle算法主要做两件事:1)只有上一个分组得到确认,才会发送下一个分组:2)收集多个小分组,在一个确认到来时一起发送. 所以,正是Nagle算法造成了发送方有可能造成粘包现…
目录 6socket套接字 7基于TCP协议的socket简单的网络通信 AF_UNIX AF_INET(应用最广泛的一个) 报错类型 单一 链接+循环通信 远程命令 9.tcp 实例:远程执行命令 10.粘包现象 11.操作系统的缓存区 1.为什么出现粘包 12.什么情况下出现粘包 1.出现粘包的情况 2.收发的本质 13.low解决粘包现象 14.recv工作原理 15.高大上版 解决粘包方式(自定制包头) 6socket套接字 socket网络套接字 什么是socket 每个 socket…
一.简单的tcp套接字通信 套接字通信的一般流程 服务端 server = socket() #创建服务器套接字 server.bind() #把地址绑定到套接字,网络地址加端口 server.listen() #监听链接 inf_loop: #服务器无限循环 conn,addr = server.accept() #接受客户端链接,建立链接conn conn_loop: #通讯循环 conn.recv()/conn.send() #通过建立的链接conn不断的对话(接收与发送消息) conn.…
只有TCP有粘包现象,UDP永远不会粘包! 粘包:在接收数据时,一次性多接收了其它请求发送来的数据(即多包接收).如,对方第一次发送hello,第二次发送world, 在接收时,应该收两次,一次是hello,一次是world,但事实上是一次收到helloworld,一次收到空,这种现象叫粘包. 原因 粘包问题主要还是因为接收方不知道消息之间的界限,不知道一次性提取多少字节的数据所造成的. 什么情况会发生: 1.发送端需要等缓冲区满才发送出去,造成粘包(发送数据时间间隔很短,数据很小,会合到一起,…
昨天我们所做的套接字是有漏洞的,它会出现粘包现象,没有发现这个问题的我们今天会进行演示.今天也会稍微讲解一下基于udp的套接字. 一.基于udp的套接字 udp是无链接的,先启动哪一端都不会报错 udp服务端: ss = socket() #创建一个服务器的套接字 ss.bind() #绑定服务器套接字 while True : #服务器无限循环 cs = ss.recvfrom()/ss.sendto() # 对话(接收与发送) ss.close() # 关闭服务器套接字 udp客户端: cs…
一.粘包现象 让我们基于tcp先制作一个远程执行命令的程序(1:执行错误命令 2:执行ls 3:执行ifconfig) 注意注意注意: res=subprocess.Popen(cmd.decode('utf-8'),shell=True,stderr=subprocess.PIPE,stdout=subprocess.PIPE) 的结果的编码是以当前所在的系统为准的,如果是windows,那么res.stdout.read()读出的就是GBK编码的,在接收端需要用GBK解码 且只能从管道里读一…
只有TCP有粘包现象,UDP永远不会粘包. 所谓粘包问题主要还是C/S两端数据传输时 因为接收方不知道消息之间的界限,不知道一次性提取多少字节的数据所造成的 根本原因:粘包是由TCP协议本身造成的,TCP为提高传输效率,发送方往往要收集到足够多的数据后才发送一个TCP段.若连续几次需要send的数据都很少,通常TCP会根据优化算法把这些数据合成一个TCP段后一次发送出去,这样接收方就收到了粘包数据. 解决方法: 1.自定义字典类型 的数据报头{文件名:a,文件的size:1090}计算出该报头的…
昨天我们所做的套接字是有漏洞的,它会出现粘包现象,没有发现这个问题的我们今天会进行演示.今天也会稍微讲解一下基于udp的套接字. 本篇导航: 基于udp的套接字 粘包现象 粘包 解决粘包方法 struct模块(了解) 一.基于udp的套接字 udp是无链接的,先启动哪一端都不会报错 udp服务端: ss = socket() #创建一个服务器的套接字 ss.bind() #绑定服务器套接字 while True : #服务器无限循环 cs = ss.recvfrom()/ss.sendto()…
一.什么是粘包 须知:只有TCP有粘包现象,UDP永远不会粘包 粘包不一定会发生 如果发生了:1.可能是在客户端已经粘了 2.客户端没有粘,可能是在服务端粘了 首先需要掌握一个socket收发消息的原理 应用程序所看到的数据是一个整体,或说是一个流(stream),一条消息有多少字节对应用程序是不可见的,因此TCP协议是面向流的协议,这也是容易出现粘包问题的原因.(因为TCP是流式协议,不知道啥时候开始,啥时候结束).而UDP是面向消息的协议,每个UDP段都是一条消息,应用程序必须以消息为单位提…
上个小节我们浅析了在Netty的使用的时候TCP的粘包和拆包的现象,Netty对此问题提供了相对比较丰富的解决方案 Netty提供了几个常用的解码器,帮助我们解决这些问题,其实上述的粘包和拆包的问题,归根结底的解决方案就是发送端给远程端一个标记,告诉远程端,每个信息的结束标志是什么,这样,远程端获取到数据后,根据跟发送端约束的标志,将接收的信息分切或者合并成我们需要的信息,这样我们就可以获取到正确的信息了 例如,我们刚才的例子中,我们可以在发送的信息中,加一个结束标志,例如两个远程端规定以行来切…
1. 基于Tcp的远程调用命令实现 很多人应该都使用过Xshell工具,这是一个远程连接工具,通过上面的知识,就可以模拟出Xshell远程连接服务器并调用命令的功能. Tcp服务端代码如下: import socket,subprocess ip_port = ("127.0.0.1",8000) tcp_server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) tcp_server.bind(ip_port) tcp_serv…
我们在前面曾经说过,发送端可以是一K一K地发送数据,而接收端的应用程序可以两K两K地提走数据,当然也有可能一次提走3K或6K数据,或者一次只提走几个字节的数据,也就是说,应用程序所看到的数据是一个整体,或说是一个流(stream),在底层通讯中这些数据可能被拆成很多数据包来发送,但是一个数据包有多少字节对应用程序是不可见的,因此TCP协议是面向流的协议,这也是容易出现粘包问题的原因.而UDP是面向消息的协议,每个UDP段都是一条消息,应用程序必须以消息为单位提取数据,不能一次提取任意字节的数据,…
1. 粘包现象及产生原因 1)概念 指TCP协议中,发送方发送的若干个包数据到接收方接收时粘成一包.发送方粘包:发送方把若干个要发送的数据包封装成一个包,一次性发送,减少网络IO延迟:接收方粘包:接收方接到的数据是若干个数据包个封装成的,而不是一个一个的数据包接收到. 一般实际开发中所说的粘包问题都是指接收方粘包现象. 2)原因分析 我们知道,我们写的应用程序是无法直接操作硬件,都是通过调用操作系统给应用程序封装的接口间接来操作硬件. 如上图所示,一个C/S系统,当你的程序要给要给远程发送数据时…
我们在前面曾经说过,发送端可以是一K一K地发送数据,而接收端的应用程序可以两K两K地提走数据,当然也有可能一次提走3K或6K数据,或者一次只提走几个字节的数据,也就是说,应用程序所看到的数据是一个整体,或说是一个流(stream),一条消息有多少字节对应用程序是不可见的,因此TCP协议是面向流的协议,这也是容易出现粘包问题的原因.而UDP是面向消息的协议,每个UDP段都是一条消息,应用程序必须以消息为单位提取数据,不能一次提取任意字节的数据,这一点和TCP是很不同的.怎样定义消息呢?可以认为对方…
1,socket套接字 一个接口模块,在tcp/udp协议之间的传输接口,将其影藏在socket之后,用户看到的是socket让其看到的. 在tcp中当做server和client的主要模块运用 #server sk = socket.socket() sk.bind(('127.0.0.1',9000))#绑定一个端口IP地址和端口 sk.listen() #接收数据 conn,addr = sk.accept() #获取接收数据的主内容和ip地址 count= conn.recv(1024)…
socket 基于tcp协议socket 服务端 import socket phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 买电话 # socket.SOCK_STREAM 流式协议 就是TCP协议 phone.bind(('127.0.0.1', 8080)) # 买电话卡 phone.listen(5) # 开机. # 5 不是链接数,链接可以产生N个,同一时刻只能监听5个请求. conn, addr = phone.…
TCP是个流协议,流没有一定界限.TCP底层不了解业务,他会根据TCP缓冲区的实际情况进行包划分,在业务上,一个业务完整的包,可能会被TCP底层拆分为多个包进行发送,也可能多个小包组合成一个大的数据包进行发送,这就是TCP的拆包和粘包. 产生问题的原因 应用程序write写入的字节大小大于套接字缓冲区大小 进行MSS大小的TCP分割: 以太网帧的payload大于MTU进行IP分片 关于MSS和MTU的分段问题可以参考https://www.cnblogs.com/yuyutianxia/p/8…
# 粘包现象 # serverimport socket sk = socket.socket()sk.bind(('127.0.0.1', 8005))sk.listen() conn, addr = sk.accept()conn.send(b'123')conn.send(b'123') # clientimport timeimport socket sk = socket.socket() sk.connect(('127.0.0.1', 8005)) time.sleep(5)msg…
转载至https://www.cnblogs.com/kex1n/p/6502002.html 在socket网络程序中,TCP和UDP分别是面向连接和非面向连接的.因此TCP的socket编程,收发两端(客户端和服务器端)都要有成对的socket,因此,发送端为了将多个发往接收端的包,更有效的发到对方,使用了优化方法(Nagle算法),将多次间隔较小.数据量小的数据,合并成一个大的数据块,然后进行封包.这样,接收端,就难于分辨出来了,必须提供科学的拆包机制. 对于UDP,不会使用块的合并优化算…
socket粘包现象分析与解决方案 简单远程执行命令程序开发(内容回顾) res = subprocess.Popen(cmd.decode('utf-8'),shell=True,stderr=subprocess.PIPE,stdout=subprocess.PIPE) #subprocess模块详情见模块详解 命令结果的编码是以当前所在的系统为准的,如果是windows,那么res.stdout.read()读出的就是GBK编码的,在接收端需要用GBK解码,且只能从管道里读一次结果 远程执…
一. 粘包现象 1. 粘包现象的由来(1)TCP属于长连接,当服务端与一个客户端进行了连接以后,其他客户端需要(排队)等待.若服务端想要连接另一个客户端,必须首先断开与第一个客户端的连接. (2)缓冲区(参考资料):a. 缓冲区(buffer),它是内存空间的一部分.也就是说,在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分预留的空间就叫做缓冲区,显然缓冲区是具有一定大小的.b. 每个socket(套接字)被创建后,都会分配两个缓冲区: 输入缓冲区和输出缓冲区.c.…
TCP协议粘包问题详解 前言 在本章节中,我们将探讨TCP协议基于流式传输的最大一个问题,即粘包问题.本章主要介绍TCP粘包的原理与其三种解决粘包的方案.并且还会介绍为什么UDP协议不会产生粘包. 基于TCP协议的socket实现远程命令输入 我们准备做一个可以在Client端远程执行Server端shell命令并拿到其执行结果的程序,而涉及到网络通信就必然会出现socket模块,关于如何抉择传输层协议的选择?我们选择使用TCP协议,因为它是可靠传输协议且数据量支持比UDP协议要大.好了废话不多…
一.数据缓冲区 缓冲区(buffer),它是内存空间的一部分.也就是说,在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分预留的空间就叫做缓冲区,显然缓冲区是具有一定大小的. 二.为什么要缓冲区 (详情参考:https://www.cnblogs.com/mlgjb/p/7991903.html) 1.可以解除高速设备与低速设备的不匹配,高速设备需要等待低速设备的制约关系,数据可以直接送往缓冲区,高速设备不用再等待低速设备,提高了计算机的效率. 2.可以减少数据的读写…
服务端: import socket import subprocess phone = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) phone.bind(("127.0.0.1", 8990)) phone.listen(10) print("运行中...") whi…
粘包现象两种 登陆 #服务端import json import socket server=socket.socket()#创建socket对象 ip_port=('127.0.0.1',8001)#获取本机回环地址和通信端口号 server.bind(ip_port)#绑定ip地址和端口号 #设置用户名和密码 username='alex' password=' server.listen()#监听服务端口号 conn,addr=server.accept() while 1: ''' fr…
粘包现象: 在socket网络程序中,TCP和UDP分别是面向连接和非面向连接的.因此TCP的socket编程,收发两端(客户端和服务器端)都要有成对的socket,因此,发送端为了将多个发往接收端的包,更有效的发到对方,使用了优化方法(Nagle算法),将多次间隔较小.数据量小的数据,合并成一个大的数据块,然后进行封包.这样,接收端,就难于分辨出来了,必须提供科学的拆包机制 对于UDP,不会使用块的合并优化算法,这样,实际上目前认为,是由于UDP支持的是一对多的模式,所以接收端的skbuff(…
服务器端程序 import struct import socket sk = socket.socket() sk.bind(('127.0.0.1',9000)) sk.listen() conn,addr = sk.accept() send_msg = input('>>>').encode() bytes_len = struct.pack('i',len(send_msg)) conn.send(bytes_len) conn.send(send_msg) # 粘包现象 co…