我们在前面曾经说过,发送端可以是一K一K地发送数据,而接收端的应用程序可以两K两K地提走数据,当然也有可能一次提走3K或6K数据,或者一次只提走几个字节的数据,也就是说,应用程序所看到的数据是一个整体,或说是一个流(stream),在底层通讯中这些数据可能被拆成很多数据包来发送,但是一个数据包有多少字节对应用程序是不可见的,因此TCP协议是面向流的协议,这也是容易出现粘包问题的原因.而UDP是面向消息的协议,每个UDP段都是一条消息,应用程序必须以消息为单位提取数据,不能一次提取任意字节的数据,…
我们在前面曾经说过,发送端可以是一K一K地发送数据,而接收端的应用程序可以两K两K地提走数据,当然也有可能一次提走3K或6K数据,或者一次只提走几个字节的数据,也就是说,应用程序所看到的数据是一个整体,或说是一个流(stream),一条消息有多少字节对应用程序是不可见的,因此TCP协议是面向流的协议,这也是容易出现粘包问题的原因.而UDP是面向消息的协议,每个UDP段都是一条消息,应用程序必须以消息为单位提取数据,不能一次提取任意字节的数据,这一点和TCP是很不同的.怎样定义消息呢?可以认为对方…
因为 TCP 本身是无边界的协议,因此它并没有结束标志,也无法分包. socket和文件不一样,从文件中读,读到末尾就到达流的结尾了,所以会返回-1或null,循环结束,但是socket是连接两个主机的桥梁,一端无法知道另一端到底还有没有数据要传输. socket如果不关闭的话,read之类的阻塞函数会一直等待它发送数据,就是所谓的阻塞. 如果发送的东西非常多必须要用循环读,可以有以下解决方案: 调用socket的 shutdownOutput 方法(Java)关闭输出流,该方法的文档说明为,将…
TCP协议中的粘包问题 1.粘包现象 基于TCP实现一个简易远程cmd功能 #服务端 import socket import subprocess sever = socket.socket() sever.bind(('127.0.0.1', 33521)) sever.listen() while True: client, address = sever.accept() while True: try: cmd = client.recv(1024).decode('utf-8') p…
一.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…
上一篇我们讲了<Socket粘包问题的3种解决方案>,但没想到评论区竟然炸了.介于大家的热情讨论,以及不同的反馈意见,本文就来做一个扩展和延伸,试图找到问题的最优解,以及消息通讯的最优解决方案. 在正式开始之前,我们先对上篇评论中的几个典型问题做一个简单的回复,不感兴趣的朋友可直接划过. 问题一:TCP存在粘包问题吗? 先说答案:TCP 本身并没有粘包和半包一说,因为 TCP 本质上只是一个传输控制协议(Transmission Control Protocol,TCP),它是一种面向连接的.…
一.粘包问题 问题1: 无法确认对方发送过来数据的大小. 'client.py' import socket client = socket.socket() client.connect( ('127.0.0.1', 9000) ) while True: cmd = input('客户端输入的内容: ') client.send(cmd.encode('utf-8')) data = client.recv(19190) print(len(data)) print(data.decode(…
socket实现客户端和服务端 tcp协议可以用socket模块实现服务端可客户端的交互 # 服务端 import socket #生成一个socket对象 soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #绑定地址跟端口号 soc.bind(('127.0.0.1', 8001)) #监听(半连接池的大小) soc.listen(5) #等着客户端来连接,conn相当于连接通道,addr是客户端的地址 conn,addr = so…
一.缓冲区 每个 socket 被创建后,都会分配两个缓冲区,输入缓冲区和输出缓冲区.write()/send() 并不立即向网络中传输数据,而是先将数据写入缓冲区中,再由TCP协议将数据从缓冲区发送到目标机器.一旦将数据写入到缓冲区,函数就可以成功返回,不管它们有没有到达目标机器,也不管它们何时被发送到网络,这些都是TCP协议负责的事情.TCP协议独立于 write()/send() 函数,数据有可能刚被写入缓冲区就发送到网络,也可能在缓冲区中不断积压,多次写入的数据被一次性发送到网络,这取决…
① TCP是个流协议,它存在粘包问题 TCP是一个基于字节流的传输服务,"流"意味着TCP所传输的数据是没有边界的.这不同于UDP提供基于消息的传输服务,其传输的数据是有边界的.TCP的发送方无法保证对等方每次接收到的是一个完整的数据包.主机A向主机B发送两个数据包,主机B的接收情况可能是 产生粘包问题的原因有以下几个: 第一 .应用层调用write方法,将应用层的缓冲区中的数据拷贝到套接字的发送缓冲区.而发送缓冲区有一个SO_SNDBUF的限制,如果应用层的缓冲区数据大小大于套接字发…
① TCP是个流协议,它存在粘包问题 TCP是一个基于字节流的传输服务,"流"意味着TCP所传输的数据是没有边界的.这不同于UDP提供基于消息的传输服务,其传输的数据是有边界的.TCP的发送方无法保证对等方每次接收到的是一个完整的数据包.主机A向主机B发送两个数据包,主机B的接收情况可能是 产生粘包问题的原因有以下几个: 第一 .应用层调用write方法,将应用层的缓冲区中的数据拷贝到套接字的发送缓冲区.而发送缓冲区有一个SO_SNDBUF的限制,如果应用层的缓冲区数据大小大于套接字发…
  主要内容: 1.read,write 与 recv,send函数. recv函数只能用于套接口IO ssize_t recv(int sockfd,void * buff,size_t len,int flags) ssize_t send(int sockfd,const void *buff,size_t len,int flags) flags为0或者为常值的或 MSG_OOB:发送或接收带外数据 (紧急数据) MSG_PEEK:窥看外来消息(接收缓冲区数据,但并不将缓冲区数据清除)…
  粘包问题:应用层要发送数据,需要调用write函数将数据发送到套接口发送缓冲区.如果应用层数据大小大于SO_SNDBUF,那么,可能产生这样一种情况,应用层的数据一部分已经被发送了,还有一部分还在套接口缓冲区待发送.此时,对方延迟接收,就容易产生粘包. 另一方面,TCP传输有MSS限制,也会对数据进行分割.第三个原因,由于MTU存在,也可能分割数据.都会产生粘包问题 粘包问题解决方案:本质上是要在应用层维护消息与消息的边界. 1.定长包 2.包尾加\r\n(FTP协议) 3.包头加上包体长度…
本文参考于CSDN博客wxy941011 1.疑问 我们使用第四个博客中的项目. 修改客户端为:连接成功后循环向服务器发送从1-100的数字.看看服务器会不会正常的接收100次数据. 可是我们发现服务器只接收了两次数据,为什么和期望的不一样呢,这就触发了粘包问题. 2.什么是粘包和拆包 当客户端不断向服务器发送数据包时,服务器就可能出现两个数据包粘在一起的情况. 而和Tcp同为传输层的Udp则不会发生粘包和拆包问题.因为Udp是基于报文发送的,从Udp帧结构可以看出,Udp首部采用了16bit来…
上个小节我们浅析了在Netty的使用的时候TCP的粘包和拆包的现象,Netty对此问题提供了相对比较丰富的解决方案 Netty提供了几个常用的解码器,帮助我们解决这些问题,其实上述的粘包和拆包的问题,归根结底的解决方案就是发送端给远程端一个标记,告诉远程端,每个信息的结束标志是什么,这样,远程端获取到数据后,根据跟发送端约束的标志,将接收的信息分切或者合并成我们需要的信息,这样我们就可以获取到正确的信息了 例如,我们刚才的例子中,我们可以在发送的信息中,加一个结束标志,例如两个远程端规定以行来切…
server端: package main import ( "bufio" "encoding/binary" "fmt" "net" "os" "unsafe" ) func SHandleError(err error, when string) { if err != nil{ fmt.Println("服务端异常退出,err=", err, when) os…
粘包现象: 粘包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…
服务端 from socket import * import subprocess,json,struct server= socket(AF_INET,SOCK_STREAM) server.bind(('127.0.0.1',8081)) server.listen(5) while True: client,client_addr=server.accept() while True: try: cmd=client.recv(1024).decode('utf-8') if not c…
Netty是目前业界最流行的NIO框架之一,它的健壮性.高性能.可定制和可扩展性在同类框架中都是首屈一指.它已经得到了成百上千的商业项目的验证,例如Hadoop的RPC框架Avro就使用了Netty作为底层通信框架,其他的业界主流RPC框架,例如:Dubbo.Google 开源的gRPC.新浪微博开源的Motan.Twitter 开源的finagle也使用Netty来构建高性能的异步通信能力.另外,阿里巴巴开源的消息中间件RocketMQ也使用Netty作为底层通信框架. TCP黏包/拆包 TC…
TCP/IP协议是一种流协议,流协议是字节流,只有开始和结束,包与包之间没有边界,所以容易产生粘包,但是不会丢包. UDP/IP协议是数据报,有边界,不存在粘包,但是可能丢包. 产生粘包问题的原因 .SQ_SNDBUF套接字本身有缓冲区(发送缓冲区,接收缓冲区) .tcp传送的网络数据最大值MSS大小限制 .链路层也有MTU(最大传输单元)大小限制,如果数据包大于>MTU要在IP层进行分片,导致消息分割.(可以简单的认为MTU是MSS加包头数据) .tcp的流量控制和拥塞控制,也可能导致粘包 .…
1 tcp有粘包及udp无粘包 - TCP 是面向连接的,面向流的可靠协议:发送端为了将多个发往接收端的包,更有效的发到对方,使用了优化方法(Nagle算法),将多次间隔较小且数据量小的数据, 合并成一个大的数据块,然后进行封包.这样,接收端,就难于分辨出来了,必须提供科学的拆包机制面向流的通信是无消息保护边界的. - UDP(用户数据报协议)是无连接的,面向消息的,提供高效率服务.不会使用块的合并优化算法,, 由于UDP支持的是一对多的模式,所以接收端的skbuff(套接字缓冲区)采用了链式结…
今日内容:socket网络编程    1.OSI七层协议    2.基于tcp协议的套接字通信    3.模拟ssh远程执行命令    4.tcp的粘包问题及解决方案    5.基于udp协议的套接字通信    6.socketserver 目标:开发一个C/S架构的软件C/S:客户端---->serverB/S:浏览器---->serverserver端:    1.位置必须固定/绑定一个固定的地址    2.对外一直提供服务,稳定运行    3.支持并发(让多个客户端感觉时被同时服务)网络…
一.Netty粘包和拆包解决方案 Netty提供了多个解码器,可以进行分包的操作,分别是: * LineBasedFrameDecoder (换行)   LineBasedFrameDecoder是回车换行解码器,如果用户发送的消息以回车换行符作为消息结束的标识,则可以直接使用Netty的LineBasedFrameDecoder对消息进行解码,只需要在初始化Netty服务端或者客户端时将LineBasedFrameDecoder正确的添加到ChannelPipeline中即可,不需要自己重新实…
scoket()模块函数用法 import socket socket.socket(socket_family,socket_type,protocal=0) 获取tcp/ip套接字 tcpsock=socket.socket(socket.AF_INET,socket.SOCK_STREAM) 获取udp/ip套接字 udpsock =socket.socket(socket.AF_INET,socket.SOCK_DGRAM) 服务端套接字函数 s.bind()    绑定(主机,端口号)…
为什么 TCP 协议有粘包问题 这部分转载自draveness博客. TCP/IP 协议簇建立了互联网中通信协议的概念模型,该协议簇中的两个主要协议就是 TCP 和 IP 协议.TCP/ IP 协议簇中的 TCP 协议能够保证数据段(Segment)的可靠性和顺序,有了可靠的传输层协议之后,应用层协议就可以直接使用 TCP 协议传输数据,不在需要关心数据段的丢失和重复问题. 图 1 - TCP 协议与应用层协议 IP 协议解决了数据包(Packet)的路由和传输,上层的 TCP 协议不再关注路由…
ssize_t recv(int s, void *buf, size_t len, int flags); --与read相比,只能用于网络套接字文件描述符 --当flags参数的值设置为MSG_PEEK时,recv可以从socket缓存中读取数据,但是不会将缓存中该部分数据清除 使用read函数直接读取socket缓存区中的内容,会清空缓存区中的内容.假设两段报文粘包,read会清空缓存 区中所有内容,从而导致后一段报文中的粘包的部分数据丢失--强调:粘包解决方案包尾加\n,必须使用recv…
阿π 专注于网络协议,系统底层,服务器软件 C++博客 | 首页 | 发新随笔 | 发新文章 | | | 管理 Socket粘包问题 这两天看csdn有一些关于socket粘包,socket缓冲区设置的问题,发现自己不是很清楚,所以查资料了解记录一下: 一两个简单概念长连接与短连接:1.长连接 Client方与Server方先建立通讯连接,连接建立后不断开, 然后再进行报文发送和接收. 2.短连接 Client方与Server每进行一次报文收发交易时才进行通讯连接,交易完毕后立即断开连接.此种方…
TCP协议中的粘包问题 1.粘包现象 基于TCP写一个远程cmd功能 #服务端 import socket import subprocess sever = socket.socket() sever.bind(('127.0.0.1', 33521)) sever.listen() while True: client, address = sever.accept() while True: try: cmd = client.recv(1024).decode('utf-8') p1 =…
一.TCP粘包 1. 什么时候考虑粘包 如果利用tcp每次发送数据,就与对方建立连接,然后双方发送完一段数据后,就关闭连接,这样就不会出现粘包问题(因为只有一种包结构,类似于http协议,UDP不会出现粘包现象).关闭连接主要要双方都发送close连接(参考tcp关闭协议).如:A需要发送一段字符串给B,那么A与B建立连接,然后发送双方都默认好的协议字符如"hello give me sth abour yourself",然后B收到报文后,就将缓冲区数据接收,然后关闭连接,这样粘包问…
Netty系列(四)TCP拆包和粘包 一.拆包和粘包问题 (1) 一个小的Socket Buffer问题 在基于流的传输里比如 TCP/IP,接收到的数据会先被存储到一个 socket 接收缓冲里.不幸的是,基于流的传输并不是一个数据包队列,而是一个字节队列.即使你发送了 2 个独立的数据包,操作系统也不会作为 2 个消息处理而仅仅是作为一连串的字节而言.因此这是不能保证你远程写入的数据就会准确地读取.举个例子,让我们假设操作系统的 TCP/TP 协议栈已经接收了 3 个数据包: 由于基于流传输…