计算机⽹络的⼋股⽂⾃述(持续更新)
计算机⽹络的⼋股⽂⾃述
1.1、三次握⼿和四次挥⼿过程,以及为什么需要三次握⼿,两次不⾏吗?为什么需要四次挥⼿呢?为什么需要等待 2MSL ,客户端才会处于关闭状态呢?
三次握⼿的过程:
1. ⾸先由客户端发送请求连接的信号,SYN=1,并进⼊Syn-Sent状态;
2. 此时服务端收到了连接请求信号后,发送SYN=1,ACK=1的连接确认报⽂,进⼊SYN-RCVD状态;
3. 客户端收到服务端的信号后,进⼊Established状态,并再次发送确认信号ACK=1;
4. 服务器收到后也转为established状态;
5. 连接完成建⽴。
三次握⼿的原因:
三次握⼿的主要⽬的就是双⽅确认⾃⼰与对⽅的发送与接收是正常的。
防⽌失效的连接请求到达服务器,让服务器建⽴错误的连接。
四次挥⼿的过程:
1. ⾸先客户端向服务器发送Fin=1的请求释放连接的信号,进⼊FIN-Wait-1状态
2. 服务器收到后发送ACK=1的确认收到释放连接信号,并进⼊CLOSE-WAIT状态
3. 客户端收到后进⼊FIN-Wait-2状态,等待服务器继续发送最后的⼀些数据
4. 服务器发送完成后发送⼀个FIN=1,ACK=1的请求释放连接信号,并进⼊LAST-ACK状态
5. 客户端收到后发送最后的ACK=1的释放连接信号,进⼊TIME-Wait状态
6. 服务器收到后关闭
7. 客户端等待2MSL后关闭
四次挥⼿的原因:
当客户端申请关闭连接的时候,可能服务器还有没有传输完成的数据,所以要在传输完所有的数据后,再发送⼀个FIN=1的数据。TIME_WAIT:
1. 确保最后⼀个确认报⽂能够到达。如果 B 没收到 A 发送来的确认报⽂,那么就会重新发送连接释放请求报⽂,A 等待⼀段时间
就是为了处理这种情况的发⽣。
2. 等待⼀段时间是为了让本连接持续时间内所产⽣的所有报⽂都从⽹络中消失,使得下⼀个新的连接不会出现旧的连接请求报⽂。
1.2、Time_wait 过多怎么办?
遇到该问题的时候,可以先从time_wait 的作⽤开始讲起,然后再讲讲⼤量的time_wait 造成了什么影响。
TIME_WAIT状态存在的理由:
1)可靠地实现TCP全双⼯连接的终⽌
在进⾏关闭连接四次挥⼿协议时,最后的ACK是由主动关闭端发出的,如果这个最终的ACK丢失,服务器将重发最终的FIN,因此客户端必须维护状态信息允许它重发最终的ACK。如果不维持这个状态信息,那么客户端将响应RST分节,服务器将此分节解释成⼀个错误(在java中会抛出connection reset的SocketException)。
因⽽,要实现TCP全双⼯连接的正常终⽌,必须处理终⽌序列四个分节中任何⼀个分节的丢失情况,主动关闭的客户端必须维持状态信息进⼊TIME_WAIT状态。
2)允许⽼的重复分节在⽹络中消逝
TCP分节可能由于路由器异常⽽“迷途”,在迷途期间,TCP发送端可能因确认超时⽽重发这个分节,迷途的分节在路由器修复后也会被送到最终⽬的地,这个原来的迷途分节就称为lost duplicate。
在关闭⼀个TCP连接后,马上⼜重新建⽴起⼀个相同的IP地址和端⼝之间的TCP连接,后⼀个连接被称为前⼀个连接的化⾝(incarnation),那么有可能出现这种情况,前⼀个连接的迷途重复分组在前⼀个连接终⽌后出现,从⽽被误解成从属于新的化⾝。
为了避免这个情况,TCP不允许处于TIME_WAIT状态的连接启动⼀个新的化⾝,因为TIME_WAIT状态持续2MSL,就可以保证当成功建⽴⼀个TCP连接的时候,来⾃连接先前化⾝的重复分组已经在⽹络中消逝。
1.3、udp如何保证可靠性呢?
参考博客:
UDP它不属于连接型协议,因⽽具有资源消耗⼩,处理速度快的优点,所以通常⾳频、视频和普通数据在传送时使⽤UDP较多,因为它们即使偶尔丢失⼀两个数据包,也不会对接收结果产⽣太⼤影响。
传输层⽆法保证数据的可靠传输,只能通过应⽤层来实现了。实现的⽅式可以参照tcp可靠性传输的⽅式,只是实现不在传输层,实现转移到了应⽤层。
实现确认机制、重传机制、窗⼝确认机制。
如果你不利⽤协议栈以及上层socket机制,⾃⼰通过抓包和发包的⽅式去实现可靠性传输,那么必须实现如下功能:
发送:包的分⽚、包确认、包的重发
接收:包的调序、包的序号确认
⽬前有如下开源程序利⽤udp实现了可靠的数据传输。分别为RUDP、RTP、UDT。
1.4、Http 短连接和长连接的区别,以及各⾃使⽤的场景,以及长连接的缺点有哪些?
HTTP协议的长连接和短连接,实质上是TCP协议的长连接和短连接。
**短连接:**就是说,浏览器和服务器每进⾏⼀次Http操作,就会建⽴⼀次连接,但是任务结束后就会中断连接;
**长连接:**在使⽤长连接的情况下,当打开⼀个⽹页完成后,客户端和服务器之间⽤于HTTP数据的Tcp 连接不会关闭。
区别:
① 服务器端空间管理上:
Keep-Alive不会永久保持连接,因为TCP连接将会越来越多,直到把服务器的TCP连接数量撑爆到上限为⽌,它有⼀个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间;
短连接对于服务器来说管理较为简单,存在的连接都是有⽤的连接,不需要额外的控制⼿段。
② 时间上:
在客户请求频繁的情况下:若使⽤短连接,将在TCP的建⽴和关闭操作上浪费时间和带宽;
若使⽤长连接,就可以节省很多这样的消耗;
java面试八股文
使⽤场景:
长连接多⽤于操作频繁,点对点的通讯,⽽且连接数不能太多情况。每个TCP连接都需要三步握⼿,这需要时间,如果每个操作都是先连接,再操作的话那么处理速度会降低很多,所以每个操作完后都不断开,次处理时直接发送数据包就OK了,不⽤建⽴TCP连接。例如:数据库的连接⽤长连接, 如果⽤短连接频繁的通信会造成socket错误,⽽且频繁的socket 创建也是对资源的浪费。
长连接可以省去较多的TCP建⽴和关闭的操作,减少浪费,节约时间。对于频繁请求资源的客户来说,较适⽤长连接。
⽽像WEB⽹站的http服务⼀般都⽤短链接,因为长连接对于服务端来说会耗费⼀定的资源,⽽像WEB⽹站这么频繁的成千上万甚⾄上亿客户端的连接⽤短连接会更省⼀些资源,如果⽤长连接,⽽且同时有成千上万的⽤户,如果每个⽤户都占⽤⼀个连接的话,那可想⽽知吧。所以并发量⼤,但每个⽤户⽆需频繁操作情况下需⽤短连接好。
长连接的缺点:
在长连接的应⽤场景下,client端⼀般不会主动关闭它们之间的连接,Client与server之间的连接如果⼀直不关闭的话,会存在⼀个问题,随着客户端连接越来越多,server早晚有扛不住的时候,从⽽导致服务器崩溃。
1.5、你的⼀个⽹站如果使⽤到长连接,那你会怎么做呢?
这时候server端需要采取⼀些策略,如关闭⼀些长时间没有读写事件发⽣的连接,这样可 以避免⼀些恶意连接导致server端服务受损;如果条件再允许就可以以客户端机器为颗粒度,限制每个客户端的最⼤长连接数,这样可以完全避免某个蛋疼的客户端连累后端服务。
1.6 TCP真的可靠吗?
TCP可以通过序列号和超时重传保证了端到端的可靠,但是它⽆法保证应⽤层⾯的可靠。
主要的故障有两类:
① 收不到FIN的故障,⽐如⽹络掉线,或者主机崩溃都是这种情况;
② 能收到FIN的故障,⽐如对⽅应⽤程序崩溃。
1.7 TCP粘包问题怎么解决?
参考博客:
**TCP粘包问题:**指发送⽅发送的若⼲数据到达接收⽅时粘成了⼀包,从接收缓冲区来看,后⼀包数
据的头紧接着前⼀包数据的尾。
粘包出现的原因:
① 发送端需要等到缓冲区满才发送出去,造成粘包;
发送⽅引起的粘包是由TCP协议本⾝造成的,TCP为了提⾼传输效率,发送⽅往往要收集到⾜够多的数据后才发送⼀包数据。若连续⼏次发送的数据都很少,通常TCP会根据优化算法把这些数据合成⼀包后⼀次性发送出去,这样接收⽅就收到了粘包数据。
② 接收⽅不及时接收缓冲区的包,造成多个包接收。
接收⽅引起的粘包是由于接收⽅⽤户进程不及时接收数据,从⽽导致粘包现象。这是因为接收⽅先把收到的数据放在系统接收缓冲区,⽤户进程从该缓冲区取数据,若下⼀包数据到达时前⼀包数据尚未被⽤户进程取⾛,则下⼀包数据放到系统接收缓冲区时就接到前⼀包数据之后,⽽⽤户进程根据预先设定的缓冲区⼤⼩从系统接收缓冲区取数据,这样就⼀次取到了多包数据。
解决粘包问题的⽅案:
① 发送固定长度的消息;
② 把消息的尺⼨与消息⼀块发送;
③ 使⽤特殊标记来区分消息间隔。
拓展–UDP会不会出现粘包的问题呢?
TCP为了保证可靠传输并减少额外的开销(每次发包都要验证),采⽤了基于流的传输,基于流的传输不认为消息是⼀条⼀条的,是⽆保护消息边界的(保护消息边界:指传输协议把数据当做⼀条独⽴的消息在⽹上传输,接收端⼀次只能接受⼀条独⽴的消息)。
UDP则是⾯向消息传输的,是有保护消息边界的,接收⽅⼀次只接受⼀条独⽴的信息,所以不存在粘包问题。
1.8 你所了解的状态码说⼀下

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。