面经总结1(TCPUDP)
Posted Zephyr丶J
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面经总结1(TCPUDP)相关的知识,希望对你有一定的参考价值。
面经总结1(TCP、UDP)
2021.8.14 第一次找工作面试(猿辅导),面试的时候答的很差,虽然我都知道,但是说的乱七八糟的,周一通知凉了
最后出了个算法题,统计有多少个岛屿,简单,两种思路,dfs和并查集,写了个dfs
所以这边系统的自己总结一下:
TCP和UDP的区别
答:TCP提供可靠的、面向连接的、点对点的运输服务,在传输数据之前,要三次握手建立连接;传输结束之后,要四次挥手断开连接;在传输过程中,提供了应答确认,超时重传,流量控制,拥塞控制等手段来保证数据的可靠性;传输速度较慢,是面向字节流的传输,首部20个字节,主要应用于对数据完整性可靠性要求高的场合,比如文件传输,邮件传输,远程登录
UDP提供不可靠的、无连接的运输服务,可以一对一,一对多,多对一,多对多交互通信,传输数据之前不需要建立连接,收到UDP数据报后不需要应答,首部8个字节,是基于消息的传输,传输速度快,主要应用于对数据实时性要求较高的场合,如语音、视频、直播等
另外:TCP报文长度会根据窗口大小和网络拥塞情况来动态变化,有拆包和粘包的机制,UDP面向用户数据报,没有粘包和拆包的机制,有保护消息边界
拆包粘包
1.什么是拆包粘包?
TCP是面向二进制字节流的协议,它会根据缓冲区的大小来对数据包进行处理,可以将一个大的数据包拆分成多个小的数据包,即拆包;也可以包多个小的数据包合并成一个大的数据包,即粘包
2.在什么情况下会发生粘包?
(1)当在短时间内,频繁发送较小的数据包,或者数据包的大小小于缓冲区的大小,这时会将通过Negal算法多个数据包合并成一个大大的数据包
(2)当接收端缓冲区接收数据的速度大于应用程序处理接收端缓冲区数据包的速度,就会将多个包缓冲下来,就有可能发送粘包
3.在什么情况下会发生拆包?
(1)当发送端发送的数据包大于发送端缓冲区的大小,将发生拆包
(2)当发送的TCP报文长度 - TCP报文头部长度大于最大报文长度MSS时,将会发生拆包
4.UDP会发生粘包现象吗,为什么?
TCP为了保证数据传输的可靠性,同时为了减少开销(每次发包都要验证),采用基于流的传输,基于流的传输不认为消息是一条一条的,没有保护消息边界(保护消息边界指的是传输协议把数据当做一条一条独立的消息在网上传输,接收端一次只能接受一条消息);而UDP是面向消息传输的,是有保护消息边界的,接收方一次只能接收一条独立的消息,所以不会产生粘包的现象
5.怎么处理拆包?
(1)发送端处理方法:如果多个分组毫不相干,甚至是并列关系,那么就将Negal算法关闭
(2)接收方不能处理粘包的现象,只能交个应用层来处理,解决方法就是循环处理读到的数据,直到数据被处理完成,而判断每条数据的 长度有两种方法:
- 1)将数据首尾加上标识符,表示数据的开始和结束(确保每条数据内部不包含开始符合结束符)
- 2)在数据中加上长度,例如用数据的前四位表示数据的长度
注意:如果http连接是短连接,请求之后,收到回答,立马断开连接,不会出现粘包。 拆包现象是有可能存在的。
Negal算法
如果发送方疯狂地向接收方发送很小的数据包,比如一次就发送1个字节,那么显然会有问题。
★TCP/IP协议中,无论发送多少数据,总是需要在数据前面加上协议头,同时,对方接收到数据,也需要发送ACK表示确认。为了尽可能的利用网络带宽,TCP总是希望尽可能的发送足够大的数据。Nagle算法就是为了尽可能发送大块数据,避免网络中充斥着许多小数据块。
Nagle算法:任意时刻,最多只能有一个未被确认的小段。所谓“小段”,指的是小于MSS尺寸的数据块,所谓“未被确认”,是指一个数据块发送出去后,没有收到对方发送的ACK确认该数据已收到。在该分组的确认到达之前不能发送其他小分组。
Nagle算法的实现规则:
如果包长度达到MSS,则允许发送;
如果该包含有FIN,则允许发送;
设置了TCP_NODELAY选项,则允许发送;
未设置TCP_CORK选项时,若所有发出去的小数据包(包长度小于MSS)均被确认,则允许发送;
上述条件都未满足,但发生了超时(一般为200ms),则立即发送。
延迟确认
如果接受方刚接收到发送方的数据包,在很短很短的时间内,又接收到第二个包。那么请问接收方是一个一个地回复好点,还是合在一起回复好呢?
★接收方收到数据包后,如果暂时没有数据要发给对端,它可以等一小段时间,再确认(Linux上默认是40ms)。如果这段时间刚好有数据要传给对端,ACK就随着数据传输,而不需要单独发送一次ACK。如果超过时间还没有数据要发送,也发送ACK,避免对端以为丢包。
但是有些场景不能用延迟确认,比如发现了乱序包、接收到了大于一个 frame 的报文,且需要调整窗口大小等。
一般情况下,Nagle算法和延迟确认不能一起使用,Nagle算法意味着延迟发,延迟确认意味着延迟接收,这样就会造成更大的延迟,会产生性能问题。
TCP三次握手四次挥手
先自己把这个图会画了,把符号都能标出来,然后看图说话
过程:
1.首先客户端发送建立连接请求,SYN=1,seq=x,客户端进入SYN-SENT状态,等待服务器端应答(SYN是同步序列编号)(服务器端处于LISTEN状态,这时会创建创建两个队列,后面补充)
2.服务器收到连接请求以后,回复这个请求,ACK=1,ack=x+1(根据序列号来的);并发送建立连接的请求,SYN = 1,seq = y;服务器端进入SYN-RECV状态
3.客户端收到服务器的SYN+ACK包以后,向服务器发送确认包ACK = 1,ack = y + 1,seq = x + 1(客户端的第二个包,第一个是x),然后进入ESTABLISHED状态
4.服务器收到以后,也进入连接状态
1.客户端发送释放连接的请求,FIN = 1,seq = u,进入FIN-WAIT1终止等待状态1,停止数据的传送
2.服务器端收到以后,作出回应,ACK= 1,ack=u+1,seq=v,进入CLOSE-WAIT关闭等待状态,服务器端还可以发送数据,客户端也需要接受
3.客户端收到服务器端的确定报文后,进入FIN-WAIT2终止等待状态2,等待服务器发送释放连接的报文
4.当服务器段发送完数据以后,向客户端发送释放连接的报文,ACK=1,ack=u+1,FIN=1,seq = w(这里不是v+1,是因为中间还传送了数据),服务器端进入LAST-ACK最后确认状态,等待客户端确认
5.客户端收到服务器端释放连接的报文,作出回应,ACK=1,ack=w+ 1,seq=u+1,客户端进入TIME-WAIT状态,等待2MSL(最大报文生存时间)时间以后关闭
6.服务器端收到客户端的确认,就进入关闭状态。可见,服务器端结束TCP连接要早一点
为什么要三次握手?而不是两次?四次?
(看了很多网上的回复,感觉答成下面这样应该可以)
是为了保证数据传输的可靠性,同时兼顾效率
防止失效的报文重新到达服务器而产生错误
如果客户端发送的第一个连接请求没有到达服务器,而是因网络原因滞留,那么客户端会重传这个请求,并与服务器建立连接;如果此时第一个连接请求到达服务器,服务器还是会回复ACK,SYN;如果是两次握手的话,又会建立起连接,但是客户端并不会回应这个消息,如果这种情况多了,会导致服务器一直在消耗资源而造成瘫痪
如果是三次连接的话,客户端收到这个过期的请求,可以查看序列号,而不做处理,服务器收不到回应,就不会建立连接
四次多余了,三次正好
为什么要四次挥手?
TCP协议是一种面向连接的、可靠的、基于字节流的运输层通信协议。TCP是全双工模式(全双工我感觉是关键)。当客户端发送FIN时,仅表示客户端没有数据发送了,但是还是可以接受服务端的数据;而服务端收到断开请求后,先回应,表示知道客户端没有数据发送了,但是服务器仍然可以将剩余的数据发送。等待发送完以后,才会再发送一个断开请求给客户端
简单地说,前 2 次挥手用于关闭一个方向的数据通道,后两次挥手用于关闭另外一个方向的数据通道。
为什么需要TIME-WAIT等待两个MSL?
1.保证连接可靠的终止
2.防止已失效的连接请求报文段出现在本次连接中
这样可以防止最后一个ACK报文丢失,如果丢失,服务器端会发送FIN报文,客户端收到后重新等待2MSL的时间
所谓的2MSL是两倍的MSL(Maximum Segment Lifetime)。MSL指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,客户端都没有再次收到FIN,那么客户端推断ACK已经被成功接收,则结束TCP连接。
还可以保证这次连接的所有数据(超时了但是没有丢失的数据)都消失了,不影响下一次连接
半连接队列和全连接队列
TCP握手前,服务端进入LISTEN状态,这时候会在内部创建两个队列,一个半连接队列(SYN队列),一个全连接队列(ACCEPT队列)
顾名思义,三次握手时,当服务器端进入SYN-RECV状态,就会加入半连接SYN队列
如果建立了连接,就会被推入全连接队列
SYN Flood攻击
是一种DDos攻击,最为经典的拒绝服务攻击,在短时间内,伪造不存在的IP地址,向服务器端发送SYN报文,当服务器回应SYN+ACK报文后,因为真实的IP地址没有发送请求,所以不会做出回应。而服务器端没有收到回应,就会进行重传,默认重传次数是五次,然后再丢弃
如果在短时间内有大量这样的SYN请求,会导致半连接队列被充满,而无法正常处理其他的TCP请求
如何处理?
从前面SYN Flood原理可以看到,消耗服务器资源主要是因为当SYN数据报文一到达,系统立即分配TCB,从而占用了资源。而SYN Flood由于很难建立起正常连接,因此,当正常连接建立起来后再分配TCB则可以有效地减轻服务器资源的消耗。常见的方法是使用Syn Cache和Syn Cookie技术。
1.SYN Cookie:在收到SYN包后,服务器会根据数据包的源地址、端口号、目的地址、端口等信息产生一个cookie作为自己的SYN/ACK包的序列号,当服务器端回复以后,服务器并不会立即分配资源进行处理,等收到客户端发送的ACK包后,重新根据相同的信息计算序列号,并与ACK包的序列号就行比对,如果相同就建立连接,否则丢弃
2.SYN Proxy防火墙
原理是syn报文首先由DDOS防护系统来响应syn_ack。带上特定的sequence number (记为cookie)。真实的客户端会返回一个ack 并且Acknowledgment number 为cookie+1。 而伪造的客户端,将不会作出响应。这样我们就可以知道那些IP对应的客户端是真实的,将真实客户端IP加入白名单。下次访问直接通过,而其他伪造的syn报文就被拦截。下面为防护示意图:
图源:https://blog.csdn.net/qq_34777600/article/details/81946514
TCP缓冲区
每个socket被创建后,都会分配两个缓冲区,一个输入缓冲区,一个输出缓冲区
缓冲区的作用:
TCP的发送缓冲区是用来缓存应用程序的数据,发送缓冲区的每个字节都有序列号,被应答确认的序列号对应的数据会从发送缓冲区删除
write/send并不是立即向网络中传输数据,而是先将数据写入输出缓冲区中,再由TCP协议将数据从缓冲区发送到目标机器。一旦写入缓冲区,函数就成功返回,不管它们有没有到达目标主机,也不管什么时候发送,这些都是由TCP协议负责的
read/recv函数同理,也是从输入缓冲区中读取,而不是直接从网络中接收数据
I/O缓冲区特性
(1)I/O缓冲区在每个TCP套接字中单独存在;
(2)I/O缓冲区在创建套接字时自动生成;
(3)即使关闭套接字也会继续传送输出缓冲区中遗留的数据;
(4)关闭套接字将丢失输入缓冲区中的数据。
输入输出缓冲区的默认大小一般都是 8K,可以通过 getsockopt() 函数获取
保活计时器
这个主要是记住这个场景,场景记住了就记住了
客户端与服务器已经建立了连接,但是客户端突然宕机,发生了故障。那么服务器就不能接收到客户端发送的数据了。这时,当然不能够让服务器一直等待下去,所以就出现了保活计时器(keepalive timer)
服务器每收到一次客户端的数据,都会刷新保活计时器;通常这个时间是两个小时;如果在两个小时之内没有收到客户端的数据,那么服务器就会发送一个探测报文,并每隔75秒发送一次,如果连续10没有回应,就会认为客户端发生了故障,就会自动断开连接。
TCP流量控制
简单来说tcp流量控制就是为了解决发送方发送速率过快而接收方处理不过来,而导致数据丢失的问题。
tcp利用滑动窗口机制来实施流量控制。
原理就是利用TCP报文首部中窗口大小的字段(win,16位)来控制,发送方的发送窗口的大小,不可以大于接收方发回的窗口大小。
每次接收方收到数据以后,会根据缓冲区的大小,计算可以接受的数据大小,并将这个值作为窗口大小附在ACK报文中给发送方回应,发送方会根据这个窗口大小改变发送窗口的大小。
零窗口问题:
但是有一种情况,如果发送方此时窗口大小为0,不发送数据。而接收方有了足够的缓存以后,发送了非零窗口的报文给发送方,但是这个报文丢失了,发送方没有收到。那么发送方的发送窗口就会一直为零而导致死锁
为了解决这个问题,TCP为每一个连接设置了一个持续计时器(persistence timer)。只要TCP的一方接收到零窗口通知,就启动这个计时器,并周期性的发送一个窗口探测报文。对方收到以后就会在确认报文中给出现在窗口的大小。
糊涂窗口综合症:
当接收方的缓冲区已经满了的时候,应用程序每次只能从缓冲区中取一个字节的数据,这时向发送方发送窗口大小为1个字节,这样的话会导致网络的利用率很低
解决这个问题的方法是让接收方缓冲区的大小足够容纳一个最长报文段或者空余空间大于缓冲区的一半时,再发送确认报文,同时发送方可以把数据累积成大的报文段进行发送(Negal算法)
(注意:TCP规定,即使设置为零窗口,也必须接收以下几种报文段:零窗口探测报文段、确认报文段和携带紧急数据的报文段)
发送窗口包含以下四个部分:
1.已经送且已经收到ACK确认
2.已发送但未收到ACK确认
3.未发送但可以发送
4.未发送且不能发送
接收窗口包括以下三个部分:
1.已成功接收并确认
2.未收到数据但可以接收
3.未收到数据且不可以接受的数据
TCP拥塞控制
先了解两个概念:
RTT:Round Trip Time 一个连接的往返时间,即数据发送时刻到接收到确认的时刻的差值
RTO: Retransmission Time Out 重传超时时间,即从数据发送时刻算起,超过这个时间便执行重传
拥塞控制和流量控制的区别:
拥塞控制是作用于网络的,防止过多的数据包注入到网络中,而出现网络负载过大的情况,拥塞的加剧会产生大量的丢包,而产生大量的超时重传,而严重影响效率
流量控制是作用于接受者的,根据接收端的接收能力控制发送端的窗口大小,防止数据的丢失
拥塞窗口(cwnd,congestion window)
只要网络中没有出现拥塞,就会将窗口的值增大一点,以便可以发送更多的数据;如果网络中出现了拥塞,那么拥塞窗口的值就减小,避免产生大量的丢包
三个阶段:
1.慢启动:
在开始发送数据时,先发送少量的数据探路,探测网络的拥塞情况。刚开始拥塞窗口的大小是1MSS(后面单位都是这个),每收到一个ACK,就会增加1;第二轮就会发送两个数据包,每收到一个ACK加1,所以第二轮增加2;以此类推,可见增长速度是指数级别的,即每经过一个RTT,cwnd就增长一倍
那么如何限制增长呢?有三种情况:
(1)如果出现了超时指示的丢包事件,那么就会把cwnd重新设置为1,把慢启动阈值(ssthresh)设置为cwnd / 2,即设置为发生拥塞时cwnd的一半
(2)如果超过了ssthresh,结束慢启动并进入拥塞避免模式,呈线性增长
(3)如果收到了连续三个冗余的ACK(什么是冗余的ACK,我认为就是发送方对一个数据报做的多次回复,之所以出现是因为当前序列号的数据可能丢失等情况发生)。那么就执行快速重传,并进入快速恢复的阶段。
2.拥塞避免:
一般来说慢启动的阈值是64K,65535字节
当cwnd达到慢启动阈值后,进入拥塞避免阶段。
在这个阶段,每收到一个ACK,拥塞窗口增加每1/cwnd;经过一次RTT,拥塞窗口的大小增加1MSS,也就是呈线性增长
那么什么时候停止增长呢,同慢启动阶段
3.拥塞发生
也就是发生丢包,这里根据前面分析的发生丢包时的情况,分成两种:
(1)第一种:发生的是超时指示的丢包;这时候认为网络拥塞情况比较严重,那么就采用RTO超时重传:
将cwnd的值设置为1,sshthresh = cwnd / 2,重新进入慢启动
(2)第二种:如果丢包事件是由三次冗余的ACK事件触发的,那么就会启动快速重传
这时拥塞窗口大小cwnd变为原来的一半,慢启动阈值也变为原来cwnd的一半,然后进入快速恢复过程
4.快速恢复:
快速恢复一般和快速重传一起使用,快速恢复认为还可以收到3个冗余得ACK,网络情况并没有那么糟,所以可以采用快速恢复
在快速重传中,已经将cwnd和阈值都变为原来cwnd的一半了
接下来进入快速恢复:
由于收到了三个冗余ACK,所以cwnd += 3;
重传需要的报文,每收到一个ACK,cwnd += 1;
如果收到新数据的ACK,表明恢复过程已经结束,将拥塞窗口设置为慢启动阈值的大小,再次进入拥塞避免阶段
(最后这一步有点争议,图上一般都是收到新的ACK直接进入拥塞避免(下图也是),但是很多地方都是写的先将拥塞窗口回复到慢启动阈值,再进入拥塞避免)
TCP保证可靠性的手段
校验和、序列号、确认应答、超时重传、连接管理、流量控制、拥塞控制
1.校验和的计算方式:
在数据传输的过程中,将发送的数据看成一个16位的整数。将这些整数相加,并且前面的进位不丢弃而是补在最后,然后取反,得到校验和。在发送数据的时候,会计算校验和,并将校验和填充到TCP头部的字段中。接收到数据以后,接收方也会计算校验和,与发送方进行比对,如果不同,数据传输一定有误;但是如果相同,数据传输也不一定成功
2.序列号和确认应答:
TCP在传输数据时,对于每一个字节都进行了编号,即序列号。
TCP在传输的过程中,每收到一次数据,就会对发送方进行确认应答,也就是发送ACK报文。这个报文中带有确认序列号,告诉发送方,哪些数据收到了,下一次需要从哪里发
序列号除了确认应答,有了序列号还可以对接收到的数据根据序列号进行排序,并去掉重复序列号的数据,是TCP保证数据传输可靠的手段之一。
3.超时重传:
如果发送方在发送数据以后,没有收到ACK报文,原因可能有两点:
(1)数据在传输过程中由于网络原因丢包,接收方没有收到
(2)接收方收到了数据,但是发送的ACK报文由于网络原因丢包了
为了解决这个问题,引入了超时重传:就是发送方在发送数据以后会等待一个时间,如果在这个时间内没有收到ACK报文,那么就重新发送。
接收方在接受到重新传送的数据后,如果是(1)情况,那么就正常回复ACK报文;如果是(2)情况,那么根据序列号,发现是重复发送的数据,就把数据丢弃,但是还是要发送ACK报文
连接管理
即三次握手四次挥手
流量控制,拥塞控制
前面聊过
流量控制
拥塞控制
TCP报文首部
记图!!!
TCP首部包括20字节的固定首部部分及长度可变的其他选项,所以TCP首部长度可变。20个字节又分为5部分,每部分4个字节32位,如图中的5行,每行表示32位。
1.源端口和目的端口字段——各占 2 字节(16位)。端口是运输层与应用层的服务接口。运输层的复用和分用功能都要通过端口才能实现。
2.序号字段——占 4 字节。TCP 连接中传送的数据流中的每一个字节都编上一个序号。序号字段的值则指的是本报文段所发送的数据的第一个字节的序号。比如分组的第一个数据包由文件的14个字节数据组成,那么该数据包所添加的序号就是1,同理第二个数据包由文件的59个字节数据组成,那么该数据包所添加的序号就是15;
3.确认号字段——占 4 字节,是期望收到对方的下一个报文段的数据的第一个字节的序号。比如接收端收到由文件14个字节数据+TCP首部组成的数据包后,删除首部提取14个字节数据,返回的确认号为15,即告诉发送端下一次应该发送文件的第15个字节及其之后字节组成的数据包过来。
4.数据偏移(即首部长度)——占 4 位,它指出 TCP 报文段的数据起始处距离 TCP 报文段的起始处有多远,也就是TCP首部的长度。“数据偏移”的单位是 32 位字(以 4 字节为计算单位),最大1111表示15x4=60个字节,即表示TCP首部最大长度为60个字节,因此“选项”部分最多40个字节。
5.保留字段——占 6 位,保留为今后使用,但目前应置为 0。
6.这里的六位二进制位,分别表示不同含义:
(1)紧急 URG —— 当 URG = 1 时,表明紧急指针字段有效。它告诉系统此报文段中有紧急数据,应尽快传送(相当于高优先级的数据)。 即URG=1的数据包不用排队直接优先传输。
(2)同步 SYN —— 同步 SYN = 1 表示这是一个连接请求或连接接受报文。即A想与B建立连接,发送过去的第一个数据包(第一次握手)中SYN=1;B返回的数据包(第二次握手)中SYN=1表示同意建立连接。
(3)确认 ACK —— 只有当 ACK = 1 时确认号字段才有效。当 ACK = 0 时,确认号无效。指示确认字段中的值是有效的
(4)PSH:指示接收方应立即将数据交给上层(了解即可)
(5)RST:用来异常的连接关闭
(6)FIN:表示断开连接
7.窗口字段 —— 占 2 字节,告知对方本方的TCP缓冲区还能存放多少数据,用来让对方设置发送窗口的依据,单位为字节。
8.检验和 —— 占 2 字节。检验和字段检验的范围包括首部和数据这两部分。在计算检验和时,要在 TCP 报文段的前面加上 12 字节的伪首部。CRC算法
9.紧急指针字段 —— 占 16 位,指出在本报文段中紧急数据共有多少个字节(紧急数据放在本报文段数据的最前面)。
10.选项字段 —— 长度可变。TCP 最初只规定了一种选项,即最大报文段长度 MSS (Maximum Segment Size)是 TCP 报文段中的数据字段的最大长度。数据字段加上 TCP 首部才等于整个的 TCP 报文段。MSS 告诉对方 TCP:“我的缓存所能接收的报文段的数据字段的最大长度是 MSS 个字节。”其他选项有:窗口扩大选项、时间戳选项、选择确认选项(SACK)。
11.填充字段 —— 这是为了使整个首部长度是 4 字节的整数倍。
补充:UDP报文头部结构首部字段只有 8 个字节,包括源端口、目的端口、长度、检验和。
RST状态
1.TCP异常终止(reset报文)
TCP的异常终止是相对于正常释放TCP连接的过程而言的,我们都知道,TCP连接的建立是通过三次握手完成的,而TCP正常释放连接是通过四次挥手来完成,但是有些情况下,TCP在交互的过程中会出现一些意想不到的情况,导致TCP无法按照正常的四次挥手来释放连接,如果此时不通过其他的方式来释放TCP连接的话,这个TCP连接将会一直存在,占用系统的部分资源。在这种情况下,我们就需要有一种能够释放TCP连接的机制,这种机制就是TCP的reset报文。reset报文是指TCP报头的标志字段中的reset位置为1的报文。
2.RST标志位(Reset)
RST表示复位,用来异常的关闭连接,在TCP的设计中它是不可或缺的。就像上面说的一样,发送RST包关闭连接时,不必等缓冲区的包都发出去(不像上面的FIN包),直接就丢弃缓存区的包发送RST包。而接收端收到RST包后,也不必发送ACK包来确认。
TCP处理程序会在自己认为的异常时刻发送RST包。例如,A向B发起连接,但B之上并未监听相应的端口,这时B操作系统上的TCP处理程序会发RST包。
又比如,AB正常建立连接了,正在通讯时,A向B发送了FIN包要求关连接,B发送ACK后,网断了,A通过若干原因放弃了这个连接(例如进程重启)。网通了后,B又开始发数据包,A收到后表示压力很大,不知道这野连接哪来的,就发了个RST包强制把连接关了,B收到后会出现connect reset by peer错误。
3.TCP异常终止的常见情形(了解):
(1)客户端尝试与服务器未对外提供服务的端口建立TCP连接,服务器将会直接向客户端发送reset报文。
(2)客户端和服务器的某一方在交互的过程中发生异常(如程序崩溃等),该方系统将向对端发送TCP reset报文,告之对方释放相关的TCP连接。
(3)接收端收到TCP报文,但是发现该TCP的报文,并不在其已建立的TCP连接列表内,则其直接向对端发送reset报文。
(4)在交互的双方中的某一方长期未收到来自对方的确认报文,则其在超出一定的重传次数或时间后,会主动向对端发送reset报文释放该TCP连接。
(5)有些应用开发者在设计应用系统时,会利用reset报文快速释放已经完成数据交互的TCP连接,以提高业务交互的效率。
利用UDP实现可靠传输
1.实现方法:
(1)将实现放到应用层,然后类似于TCP,实现确认机制、重传机制和窗口确认机制;
(2)给数据包进行编号,按顺序接收并存储,接收端收到数据包后发送确认信息给发送端,发送端接收到确认信息后继续发送,若接收端接收的数据不是期望的顺序编号,则要求重发;(主要解决丢包和包无序的问题)
2.已经实现的可靠UDP:
(1)RUDP 可靠数据报传输协议;
(2)RTP 实时传输协议
为数据提供了具有实时特征的端对端传送服务;例如:组播或单播网络服务下的交互式视频、音频或模拟数据。
(3)UDT
基于UDP的数据传输协议,是一种互联网传输协议; 主要目的是支持高速广域网上的海量数据传输,引入了新的拥塞控制和数据可靠性控制机制(互联网上的标准数据传输协议TCP在高带宽长距离的网络上性能很差);
UDT是面向连接的双向的应用层协议,同时支持可靠的数据流传输和部分可靠的数据报服务;
应用:高速数据传输,点到点技术(P2P),防火墙穿透,多媒体数据传输;
以上是关于面经总结1(TCPUDP)的主要内容,如果未能解决你的问题,请参考以下文章
Java开发三年的面经总结,一份面试阿里网易的面经(高开岗)