计算机网络面试题汇总

Posted 快乐代码小猪

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了计算机网络面试题汇总相关的知识,希望对你有一定的参考价值。

文章目录

TCP/IP体系结构

1. TCP/IP的四层模型指的是哪些?

TCP/IP按照层次划分,可以分为以下四层 :

网络接口层:对应物理层和数据链路层

网络层

传输层

应用层:包括会话层、表示层、应用层

各层举例如下表所示:

网络接口层控制操作系统,硬件设备驱动.网络适配器等等硬件设备
网络层IP
传输层TCP(传输控制协议),UDP(用户数据报协议)
应用层FTP(文件传输协议),DNS(域名系统),HTTP(超文本传输协议)

2. OSI的七层模型

  • 物理层:在物理信道上实现原始比特流的传输。(以太网, IEEE 802.2 等)
  • 数据链路层:实现无差错地将数据帧(将网络层的数据封装成数据帧,便于物理层传输)从一个节点传送到下一个相邻节点。(Wi-Fi(IEEE 802.11) , WiMAX(IEEE 802.16), GPRS, HDLC, PPP 等协议)
  • 网络层:实现将数据分组从源站通过网络传送到目的站,即网络上一台主机与另一台主机之间的数据传输。(IP, ICMP, IGMP, ARP, RARP, OSPF 等协议)
  • 传输层:实现源端到目的端数据的传输,即某主机的某进程与另一台主机的某进程之间的数据传输。(TCP, UDP 等协议)
  • 会话层:实现在不同机器上用户建立、维护和终止会话关系。即会话层对会话提供控制管理服务、会话同步服务等。(ZIP, ASP, SSH 等协议)
  • 表示层:确保各种通信设备能够互相操作,不及考虑其数据的内部表示。即确保即使各种通信设备其数据的内部表示不同,但仍然能相互正确操作。(SSL等协议)
  • 应用层:使用户能够访问网络,为各类应用提供相应的服务、提供各种用户接口支持服务。应用层不是应用程序,应用层是一个为应用程序提供各类应用支持的服务层。(HTTP, FTP, SMTP, POP3, DHCP, DNS等协议)

五层模型的作用 : (字节跳动)

物理层 : 在物理信道中实现原始的比特流的传输(物理层协议例如以太网,IEEE 808.2等等)

数据链路层 : 实现将数据帧(将网络层的数据封装成数据帧),从一个节点传送到另一个节点

网络层 : 实现将数据分组从源站通过网络传送到目的站,即我们说的网络上一台主机与另一台主机的数据传输,其中IP,ARP协议即为网络层协议

传输层 : 实现源端到目的端数据的传输,即某主机的某个进程与另一个主机的某一个进程之间的数据传输,TCP,UDP

应用层 : 是用户能够访问网络,为各类应用提供相应的服务,提供各种用户接口支持服务

在七层模型中,还多出来了两层 :

表示层 : 确保各种通信设备能够互相操作,不及考虑其数据的内部表示。即确保即使各种通信设备其数据的内部表示不同,但仍然能相互正确操作。(SSL等协议)

会话层:实现在不同机器上用户建立、维护和终止会话关系。即会话层对会话提供控制管理服务、会话同步服务等。(ZIP, ASP, SSH 等协议)

TCP、UDP的区别

TCP和UDP是TCP/IP体系结构运输层中的两个重要协议

TCP(Transmission Control Protocol):传输控制协议

UDP(User Datagram Protocol):用户数据报协议

(1)TCP:面向有连接,可靠的,速度慢,效率低。

(2)UDP:面向无连接, 不可靠,速度快,效率高。

当进程需要传输可靠的数据时应使用TCP,当进程需要高效传输数据,可以忽略可靠性时应使用UDP协议

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2M2v5aZL-1632465301638)(.\\imgs\\TCP和UDP的区别.jpg)]

注意 : UDP的不可靠性就在于它的面向无连接的,不需要建立连接,就可以发送数据,即UDP只会把想发的数据报文一股脑的丢给对方,并不在意数据有无安全完整到达.

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-adxLq68d-1632465301641)(.\\imgs\\UDP.gif)]

如何在应用层保证udp可靠传输

因为udp是面向无连接的,不能保证传输的可靠性,此时我们只能在应用层实现可靠传输

目前有如下开源程序利用udp实现了可靠的数据传输。分别为RUDP、RTP、UDT

RUDP

​ RUDP 提供一组数据服务质量增强机制,如拥塞控制的改进、重发机制及淡化服务器算法等,从而在包丢失和网络拥塞的情况下, RTP 客户机(实时位置)面前呈现的就是一个高质量的 RTP 流。在不干扰协议的实时特性的同时,可靠 UDP 的拥塞控制机制允许 TCP 方式下的流控制行为。

RTP

​ 实时传输协议(RTP)为数据提供了具有实时特征的端对端传送服务,如在组播或单播网络服务下的交互式视频音频或模拟数据。应用程序通常在 UDP 上运行 RTP 以便使用其多路结点和校验服务;这两种协议都提供了传输层协议的功能。但是 RTP 可以与其它适合的底层网络或传输协议一起使用。如果底层网络提供组播方式,那么 RTP 可以使用该组播表传输数据到多个目的地。

RTP 本身并没有提供按时发送机制或其它服务质量(QoS)保证,它依赖于底层服务去实现这一过程。 RTP 并不保证传送或防止无序传送,也不确定底层网络的可靠性。 RTP 实行有序传送, RTP 中的序列号允许接收方重组发送方的包序列,同时序列号也能用于决定适当的包位置,例如:在视频解码中,就不需要顺序解码。

UDT

​ 基于UDP的数据传输协议(UDP-basedData Transfer Protocol,简称UDT)是一种互联网数据传输协议。UDT的主要目的是支持高速广域网上的海量数据传输,而互联网上的标准数据传输协议TCP在高带宽长距离网络上性能很差。顾名思义,UDT建于UDP之上,并引入新的拥塞控制和数据可靠性控制机制。UDT是面向连接的双向的应用层协议。它同时支持可靠的数据流传输和部分可靠的数据报传输。由于UDT完全在UDP上实现,它也可以应用在除了高速数据传输之外的其它应用领域,例如点到点技术(P2P),防火墙穿透,多媒体数据传输等等

TCP流量控制

流量控制:让发送方的发送速率不要太快,要让接收方来得及接收

利用滑动窗口机制可以很方便地在TCP连接上实现对发送方的流量控制

假设A发送的每个TCP数据报文段可携带100字节数据;

在A和B建立连接时,B告诉A:我的接收窗口为400;

于是,A将自己的发送窗口也设置为400,也就是能发送1-400的数据



当B又有存储空间时,会向A发送窗口值,则A又可以继续发送数据了

但是如果B发送的这个窗口值丢失,就会造成死锁

解决:

当A收到的窗口值为0时就开启一个持续计时器,当持续计时器超时,会向B发送一个零窗口探测报文

如果B返回的窗口还是0,A就重新启动持续计时器

零窗口探测报文也会丢失,解决:零窗口探测报文也存在一个重传计时器

在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络性能就要变坏,这种情况就叫做网络拥塞.

TCP拥塞控制

若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络性能就会变坏,这种情况叫网络拥塞

网络拥塞的原因主要有以下三点:

  • 处理器的速度太慢
  • 线路容量的限制
  • 节点输出包的能力小于输入包的能力

而我们所说的TCP的拥塞控制和流量控制的原理是相关的 :

流量控制在数据链路层对一条通信路径上的流量进行控制,其的是保证发送者的发送速度不超过接收者的接收速度,它只涉及一全发送者和一个接收者,是局部控制。

拥塞控制是对整个通信子网的流量进行控制,其目的是保证通信子网中的流量与其资源相匹配,使子网不会出现性能下降和恶化、甚至崩溃,是全局控制。

拥塞控制的目的:

  • 防止由于过载而使得吞吐量下降,损失效率
  • 合理分配网络资源
  • 避免死锁
  • 匹配传输速度

拥塞控制的方法:

开环控制: 开环控制的思想是通过良好的设计避免拥塞问题的出现,确保拥塞问题在开始时就不可能发生。开环控制方法包括何时接受新的通信何时丢弃包、丢弃哪些包。其特点是在作出决定时不考虑网络当前的状态

闭环控制: 闭环控制的思想是反馈控制。即通过将网络工作的动态信息反馈给网络中节点的有关进程,节点根据网络当前的动态信息,调整转发数据包的策略。闭环控制过程包括三部分:

监视系统 检测网络发生或将要发生拥塞的时间和地点

报告 将监视中检测到的信息传送到可以进行拥塞控制的节点

决策 调整系统的操作行为,以解决问题

拥塞控制的常见算法:

  • 1.慢开始 : 先指数级增长连接,到达阈值时,保持不变…
  • 2.拥塞控制 : 每一次只增1(线性增长)
  • 3.快重传 : 有没有在规定时间内返回响应…
  • 4.快恢复

发送方维护一个拥塞窗口的状态变量cwnd,其值取决于网络的拥塞程度,且动态变化。发送方将拥塞窗口作为发送窗口swnd = cwnd。发送方维护一个慢开始门限ssthresh状态变量。

拥塞窗口的维护原则:只要网络没有出现拥塞,拥塞窗口就增大;出现拥塞,拥塞窗口就减小。

判断是否出现网络拥塞的依据:判断有没有按时收到确认报文。

cwnd < ssthresh慢开始

cwnd >=ssthresh拥塞控制

1.慢开始

初始拥塞窗口cwnd=1,发送方只能发送1个数据报文(cwnd是几,就发送几个),接收方收到报文,发送1个确认报文;

拥塞窗口变为cwnd=2,发送方发送2个数据报文,接收方收到报文,发送2个确认报文;

拥塞窗口cwnd=4。发送方发送4个报文数据,接收方收到报文,发送4个确认报文;

拥塞窗口cwnd=8 …

拥塞窗口cwnd=16(cwnd按指数增长)

当拥塞窗口值>=慢开始门限时,改为拥塞控制算法

2.拥塞控制

拥塞控制:cwnd只能每次线性+1。

拥塞窗口cwnd=16。发送方发送16个报文数据,接收方收到报文,发送1个确认报文;

拥塞窗口cwnd=17。发送方发送17个报文数据,接收方收到报文,发送1个确认报文;

拥塞窗口cwnd=18。发送方发送18个报文数据,接收方收到报文,发送1个确认报文;

拥塞窗口cwnd=18(cwnd线性增长)

如果发送方发送了24个报文,但是只接收到了20个确认报文,丢失的4个报文的重传计时器超时了,

发送方判断出现拥塞,重置ssthresh=cwnd/2;cwnd=1

3.快重传-快恢复

快重传-快恢复:使发送方尽快重传,而不是等重传计时器超时再重传。

(发送M1,确认M1;发送M2,确认M2;发送M3,M3丢失;发送M4,确认M2;发送M5,确认M2;发送M6,确认M2;)收到3个重复的确认,立即重传。

快恢复:ssthresh=cwnd/2;cwnd=ssthren(丢失了3个报文段,拥塞窗口可以不置为1)

综合

TCP的三次握手过程

所谓三次握手,是指建立一个TCP连接时,需要客户端和服务器总共发送 3个包

三次握手的目的是: 客户端连接服务器到指定的端口,建立TCP连接.并同步连接双方的序列号和确认号并交换TCP窗口大小信息.

在Socket编程中,客户端执行connect()时,将触发三次握手

首先我们需要知道以下四个概念:

序列号seq: 占4个字节,用来标记数据段的顺序,就是这个报文段中的第一个字节的数据编号

确认号ack: 占4个字节,期待收到对方下一个报文段的第一个数据字节的序号

同步SYN: 连接建立时用于同步序号。

​ 当SYN=1,ACK=0时表示:这是一个连接请求报文段。

​ 若同意连接,则在响应报文段中使得SYN=1,ACK=1。因此,SYN=1表示这是一个连接请求,或连接接受报文。

​ SYN这个标志位只有在TCP建产连接时才会被置1,握手完成后SYN标志位被置0。

确认ACK: 占1位,仅当ACK=1时,确认号字段才有效。ACK=0时,确认号无效

  • 第一次握手: 建立连接时,客户端A发送SYN包(seq = x)到服务器B,并进入SYN_SEND状态,等待服务器B确认
  • 第二次握手: 服务器B收到服务器发送的SYN包.必须确认客户端A的SYN(ack = x + 1,seq = y),同时自己也会发送一个SYN包,即SYN + ACK包,此时服务器进入SYN_RECV状态
  • 第三次握手: 客户端A收到服务器B的SYN包 + ACK包,向服务器B发送确认包ACK,此时无需将SYN标识置为1(seq = x + 1,ack = y + 1),此包发送完毕,客户端A和服务器B进入ESTABLISHED状态
  • 完成三次握手以后,客户端和服务器端即可以开始进行传送数据

能否变为二次握手

滞留在网络中的请求到达服务器,会导致服务器给客服发送请求,并进入已建立连接状态;

服务器不理睬该请求,仍为关闭状态

服务器处于已建立连接状态会等待客户端的请求,造成服务器资源浪费

accept connect listen对应三次握手什么阶段

客户端调用connect的时候,就是发一个syn包

服务端accept的时候,实际上是从内核的accept队列里面取一个连接,如果这个队列为空,则进程阻塞(阻塞模式下)。如果accept返回则说明成功取到一个连接,返回到应用层。

大致的过程是客户端发一个syn之后,服务端将这个连接放入到backlog队列,在收到客户端的ack之后将这个请求移到accept队列。所以accept一定是发生在三次握手之后,connect只是发一个syn而已

Accept根本不参与三次握手,服务器只要Listen,客户端connect是与服务器内核握手,connect完成之后,服务器都不需要写Accept,客户端就已经可以发送数据了,你完全可以让这批数据在服务器里躺一年之后,再Accept也可以

tcp三次握手的过程,accept发生在三次握手哪个阶段?

第一次握手:客户端发送syn包(syn=j)到服务器。
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个ASK包(ask=k)。
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1)。
三次握手完成后,客户端和服务器就建立了tcp连接。这时可以调用accept函数获得此连接

TCP的四次挥手过程

TCP通信双方都可以释放连接

TCP的连接的拆除需要发送四个包,因此称为四次挥手。客户端或服务器均可主动发起挥手动作,在socket编程中,任何一方执行close()操作即可产生挥手操作。

TCP连接是全双工的,因此每个方向都必须单独进行关闭。这原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。

  • (1) TCP客户端发送一个FIN,用来关闭客户端到服务器端的数据传送(即告诉服务器我要和你断开连接)
  • (2) 服务器收到这个FIN,它会发送一个ACK,确认序号为收到的序号加1.和SYN一样,一个FIN将占用一个序号(即告诉客户端你不能给我发了,但是此时服务器端还是可以给客户端发送信息的)
  • (3) 服务器端关闭与客户端的连接,发送一个FIN包给客户端(此时服务器端也告诉客户端我也要和你断开连接)
  • (4) 客户端发送ACK报文确认,并将确认序号设置为收到的序号加1(客户端同意了服务器端的请求,此时确认以后,服务器端也不能给服务器端发送数据了)

以第一次挥手为例各个标志位的含义:

FIN:表明这是一个TCP连接释放报文段

ACK:对之前接收的报文段进行确认

ack:服务端传送过来的字节的最后一个字节序号+1

seq:客户端发送字节的最后一个字节序号+1

客户端时间等待状态是否有必要?

如果客户端最后一次挥手发送过程中丢失,会导致服务器一直重传TCP连接释放,无法进入关闭状态

添加等待状态可以确保服务器收到最后一个TCP确认报文段而进入关闭状态,另外,客户端在发完最后一个TCP确认报文段后再经过2MLS,可以使本次连接持续时间内所产生的所有报文段都从网络中消失,使下一个TCP连接中不会出现旧连接中的报文段。

如果客户端出现故障,客户端如何发现?

TCP服务器每次收到一次TCP客户端进程的数据,就重新设置并启动保活计时器(2h),若保活周期内未收到TCP客户端的数据,TCP服务器就像TCP客户端发送探测报文段,以后每75s发送一次,若一脸发送10个仍没收到TCP客户端的响应,TCP服务端就认为TCP客户端出现了故障,接着就关闭这个链接。

四次挥手timewait

当客户端最后一次发送消息时并没有直接进入close状态而是进入TIME_WAIT状态,这是因为TCP是面向连接的协议,每一次发送都需要确认对方是否收到消息。客户端最后一次发送消息时可能会由于网络等其他原因导致服务器收不到消息,服务器就会选择从新给客户端发送一个FIN的包,如果客户端处于关闭状态将永远也收不到服务器发给它的消息了。至于这个时间要等多久才能确认对方收到了消息呢。
报文在网络中有一个最大生存时间MSL超过这个时间就会被丢弃并通知源主机。
TIME_WAIT 要等待 2MSL 才会进入 CLOSED 状态。
ACK包到达服务器需要MSL时间,服务器重传 FIN 包也需要MSL时间,2MSL 是数据包往返的最大时间,通常为2min,如果2MSL后还未收到服务器重传的FIN,就说明服务器已经收到了ACK,此时由TIME_WAIT状态转变为CLOSED状态.

tcp keepalive实现原理

TCP的keepalive的来源

双方建立交互的连接,但是并不是一直存在数据交互,有些连接会在数据交互完毕后,主动释放连接,而有些不会,那么在长时间无数据交互的时间段内,交互双方都有可能出现掉电、死机、异常重启等各种意外,当这些意外发生之后,这些TCP连接并未来得及正常释放,那么,连接的另一方并不知道对端的情况,它会一直维护这个连接,长时间的积累会导致非常多的半打开连接,造成端系统资源的消耗和浪费,为了解决这个问题,在传输层可以利用TCP的保活报文来实现。

TCP的keepalive的作用

利用保活探测功能,可以探知这种对端的意外情况,从而保证在意外发生时,可以释放半打开的TCP连接。

tcp三次握手四次挥手过程及各个状态

三次握手状态:

(1) 第一次握手[同步已发送状态,SYN-SENT]

(2) 第二次握手[同步收到状态,SYN-REVD]

(3) 第三次握手[已建立连接状态,ESTABLISHED]

四次挥手状态:

(1) FIN-WAIT-1(终止等待1)状态[客户端]

(2) CLOSE-WAIT(关闭等待)状态[服务端]

(3) FIN-WAIT-2(终止等待2)状态[客户端]

(4) LAST-ACK(最后确认)状态[服务端]

(5) TIME-WAIT(时间等待)状态[客户端] 这个是考点!!!

(6) CLOSED状态[服务端]

为什么三次为什么四次

TCP连接为什么是三次的问题?

TCP协议为了实现可靠传输,通信双方需要判断自己已经发送的数据包是否都被接收方收到, 如果没收到, 就需要重发。 为了实现这个需求,很自然地就会引出序号(sequence number)确认号(acknowledgement number) 的使用。

故为了可靠传输,发送方和接收方始终需要同步SYN序号,不仅客户端向服务器端发送SYN包请求连接,并且服务器端发送ACK包(确认包)同意请求,也需要向客户端发送SYN包请求连接,并得到客户端的ACK包(确认包),只有双方都发送并接收响应,才算连接成功!

TCP断开连接为什么是四次的问题?

TCP协议是一种面向连接的、可靠的、基于字节流的运输层通信协议。

TCP是全双工模式,这就意味着,当客户端发出FIN报文段给服务器端时,只是表示客户端已经没有数据要发送了,即表示它的数据已经全部发送完毕了;但是,这个时候客户端还是可以接受来自服务器端的数据的;当服务器端返回ACK报文段时,表示它已经知道了客户端没有数据发送了,但是服务器还是可以发送数据到客户端的;当服务器也发送了FIN报文段时,这个时候就表示客户端也没有数据要发送了,就等于告诉我也没有数据要发送了,之后等到客户端返回ACK报文段的时候,彼此才会真正的,愉快的中断这次TCP连接。

SYN攻击是什么?

我们说在建立TCP连接的过程中,服务器发送SYN-ACK包之后,收到客户端的ACK包之前的状态叫做半连接状态,此时服务器处于SYN-RECV状态,当服务器收到ACK包后,称为ESTABLISHED状态

**SYN攻击指的是攻击客户端,在短时间内伪造出大量的不存在的IP地址,向服务器端进行发送SYN包,此时服务器回复确认包(ACK),并等待客户端的确认,由于很大的IP地址是不存在的,导致服务器需要不断地进行重复发送直至超时!**而这些伪造的SYN包将长时间占用未连接队列,正常的SYN请求被丢弃,目标系统运行缓慢,严重者将引起网络堵塞甚至系统瘫痪.

解决方案:

在Linux系统下可以如下命令检测是否被Syn攻击

netstat -n -p TCP | grep SYN_RECV

一般较新的TCP/IP协议栈都对这一过程进行修正来防范Syn攻击,修改tcp协议实现。主要方法有SynAttackProtect保护机制、SYN cookies技术、增加最大半连接和缩短超时时间等等,但是都不能完全地防范SYN攻击.

TCP建立连接过程中,第三次握手seq=1000,ack=2000.问第二次握手seq和ack分别为多少?

首先我们需要知道几个概念:

  • 序列号seq: 占4个字节,用来标记数据段的顺序,就是这个报文段中的第一个字节的数据编号
  • 确认号ack: 占4个字节,期待收到对方下一个报文段的第一个数据字节的序号
  • 同步SYN: 连接建立时用于同步序号。当SYN=1,ACK=0时表示:这是一个连接请求报文段。若同意连接,则在响应报文段中使得SYN=1,ACK=1。因此,SYN=1表示这是一个连接请求,或连接接受报文。SYN这个标志位只有在TCP建产连接时才会被置1,握手完成后SYN标志位被置0。
  • 确认ACK: 占1位,仅当ACK=1时,确认号字段才有效。ACK=0时,确认号无效
第一次握手:建立连接时,客户端发送SYN包(seq=x)到服务器,并进入SYN_SENT状态,等待服务器确认;SYN:同步序列编号(Synchronize Sequence Numbers)。
第二次握手:服务器收到SYN包,将SYN和ACK标识都置为1,然后设置(seq=y,ack=x+1),向客户端发送一个SYN+ACK包,此时服务器进入SYN_RECV状态.
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包,将ACK置为1,S此时无需SYN,(seq=x+1,ack=y+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。

所以 :

这题中,第三次的seq = x + 1 = 2000,ack = y + 1 = 1000,说明第二次的seq = y = 1999,ack = x + 1 = 1000

tcp粘包

什么是TCP粘包?

TCP粘包就是指发送方发送的若干包数据到达接收方时粘成了一包,从接收缓冲区来看,后一包数据的头紧接着前一包数据的尾,出现粘包的原因是多方面的,可能是来自发送方,也可能是来自接收方。

粘包产生的原因

(1) 发送方原因

TCP默认使用Nagle算法(主要作用:减少网络中报文段的数量),而Nagle算法主要做两件事:

  1. 只有上一个分组得到确认,才会发送下一个分组
  2. 收集多个小分组,在一个确认到来时一起发送

Nagle算法造成了发送方可能会出现粘包问题

(2) 接收方原因

TCP接收到数据包时,并不会马上交到应用层进行处理,或者说应用层并不会立即处理。实际上,TCP将接收到的数据包保存在接收缓存里,然后应用程序主动从缓存读取收到的分组。这样一来,如果TCP接收数据包到缓存的速度大于应用程序从缓存中读取数据包的速度,多个包就会被缓存,应用程序就有可能读取到多个首尾相接粘到一起的包。

如何解决粘包问题

(1)发送方

对于发送方造成的粘包问题,可以通过关闭Nagle算法来解决,使用TCP_NODELAY选项来关闭算法

(2)接收方

接收方没有办法来处理粘包现象,只能将问题交给应用层来处理。

(2)应用层

应用层的解决办法简单可行,不仅能解决接收方的粘包问题,还可以解决发送方的粘包问题。

解决办法:循环处理,应用程序从接收缓存中读取分组时,读完一条数据,就应该循环读取下一条数据,直到所有数据都被处理完成,但是如何判断每条数据的长度呢?

  • 格式化数据每条数据有固定的格式(开始符,结束符),这种方法简单易行,但是选择开始符和结束符时一定要确保每条数据的内部不包含开始符和结束符。
  • 发送长度:发送每条数据时,将数据的长度一并发送,例如规定数据的前4位是数据的长度,应用层在处理时可以根据长度来判断每个分组的开始和结束位置。

UDP会不会产生粘包问题呢?

TCP为了保证可靠传输并减少额外的开销(每次发包都要验证),采用了基于流的传输,基于流的传输不认为消息是一条一条的,是无保护消息边界的(保护消息边界:指传输协议把数据当做一条独立的消息在网上传输,接收端一次只能接受一条独立的消息)。

UDP则是面向消息传输的,是有保护消息边界的,接收方一次只接受一条独立的信息,所以不存在粘包问题。

举个例子:有三个数据包,大小分别为2k、4k、6k,如果采用UDP发送的话,不管接受方的接收缓存有多大,我们必须要进行至少三次以上的发送才能把数据包发送完,但是使用TCP协议发送的话,我们只需要接受方的接收缓存有12k的大小,就可以一次把这3个数据包全部发送完毕。

XSS(Cross Site Scripting) 跨域脚本攻击

攻击原理 :

XSS攻击的核心原理是:不需要你做任何的登录认证,它会通过合法的操作(比如在url中输入、在评论框中输入),向你的页面注入脚本(可能是js、hmtl代码块等)
最后导致的结果可能是:盗用Cookie破坏页面的正常结构,插入广告等恶意内容D-doss攻击

如何防御XSS攻击?

  • 编码 :把js代码转义成字符串
  • 过滤 :移除用户输入的和事件相关的属性。如onerror可以自动触发攻击,还有onclick等。(总而言是,过滤掉一些不安全的内容)移除用户输入的Style节点、Script节点、Iframe节点。(尤其是Script节点,它可是支持跨域的呀,一定要移除)。
  • 校正:避免直接对html Entity进行解码。使用DOM Parse转换,校正不配对的DOM标签。DOM Parse这个概念,它的作用是把文本解析成DOM结构。比较常用的做法是,通过第一步的编码转成文本,然后第三步转成DOM对象,然后经过第二步的过滤。

CSRF(Cross-Site Request Forgery) 跨站请求伪造

攻击原理 :

如何防御CSRF攻击?

  • Token 验证:(用的最多)

(1)服务器发送给客户端一个token;
(2)客户端提交的表单中带着这个token。
(3)如果这个 token 不合法,那么服务器拒绝这个请求。

  • 隐藏令牌:把 token 隐藏在 http 的 head头中。方法二和方法一有点像,本质上没有太大区别,只是使用方式上有区别。

  • Referer 验证:Referer 指的是页面请求来源。意思是,只接受本站的请求,服务器才做响应;如果不是,就拦截。

XSS和CSRF区别

  • csrf中B利用C获取A的信任,得到cookie,再破坏A;XSS:不需要登录。
  • csrf利用A本身的漏洞;xss注入js代码,篡改a的内容。

sql注入和防范(美团)

什么是SQL注入?

简单的理解,SQL注入就是我们将SQL命令插入到WEB表单或者是页面请求url的请求字符串,最终达到欺骗服务器的执行恶意的SQL命令的目的

总结来说,SQL注入就是指通过构建特殊的输入作为参数传入WEB应用程序,而这些输入大多数情况下都是SQL语法中的一些组合,通过执行SQL语句进而执行了攻击者携带的操作。

导致SQL注入的主要原因是没有细致地过滤用户输入的数据,致使非法数据侵入系统

SQL注入的典型案例 - 用户登录问题

案例 : 我们在用户登录的时候,需要输入用户名和密码进行登录,此时如果我们没有防范SQL注入,在用户登录信息中输入以下信息,将会免密登录,这导致对我们的系统造成了极大的不安全性!

用户名 :or 1 = 1 –

密码 :

首先我们来说一下后台验证用户名和密码的SQL语句为 :

select * form user_table where username = 'username' and password = 'password';

此时我们输入上面的用户名和密码以后 :

select * form user_table where username = '' or 1 = 1 -- and password = 'password';

这里就会出现问题了:

我们说在SQL语句中, – 表示注释,此时 1 = 1为true,前面用 ‘or‘进行连接,则该条件一定成立,故我们登陆成功

此时如果我们注入的语句不是登陆,而是删除数据表结构,那如果没有对SQ注入进行防范,这样的危害是及其大的!!!

SQL防范

1. 对于普通用户和系统管理员用户的权限进行严格的划分

如果是对数据库的一些删除,建立等操作,我们需要系统管理用户才能进行操作,即我们在设计数据库时,把系统管理员的用户与普通用户区分开来。

2.强迫使用参数化语句

如果在编写SQL语句的时候,用户输入的变量不是直接嵌入到SQL语句。而是通过参数来传递这个变量的话,那么就可以有效的防治SQL注入式攻击

3. 加强对用户输入的验证

加强对用户输入内容的检查与验证

4. 使用预编译(PreStatement)

PreparedStatement会对SQL进行了预编译,在第一次执行SQL前数据库会进行分析、编译和优化,同时执行计划同样会被缓存起来,它允许数据库做参数化查询。在使用参数化查询的情况下,数据库不会将参数的内容视为SQL执行的一部分,而是作为一个字段的属性值来处理,这样就算参数中包含破环性语句(or ‘1=1’),也只能作为参数,而不能作为SQL语句内容,故不会被执行

大部分的SQL框架,例如: Hibernate,Mybatis,JPA等都支持预编译,故能够防范SQL注入问题

HTTP/TCP/IP

1. HTTP(HyperText Transport Protocol)

HTTP是超文本传输协议的缩写,它是用来传送WWW方式的数据,按层次划分,它属于应用层.HTTP协议采用了请求/响应模型.

2. TCP(Transmission Control Protocol )

TCP是指传输控制协议,是一种面向连接的,可靠的,基于字节流的传输层通信协议. 其中用户数据报协议(UDP)也是传输层另一种重要的传输协议(后面会进行比较) ,他属于传输层

3. IP(Internet Protocol)

IP指的是网络之间互连的协议,也就是为计算机网络相互连接进行通信而设计的协议,它属于网络层.

如今的IP网络使用32位地址,以点分十进制表示,如192.168.0.1

地址格式为:IP地址 = 网络地址+主机地址 或 IP地址 = 网络地址 + 子网地址 + 主机地址

HTTP的报文结构

一个HTTP请求报文由四个部分组成 : 请求行、请求头部、空行和请求数据(请求体)

一个HTTP响应报文也由四个部分组成:状态行、响应头部,空行和响应体

HTTP与HTTPS的区别

HTTP协议传输的数据都是未加密的,也就是明文的,因此使用HTTP协议传输隐私信息非常不安全,为了保证这些隐私数据能加密传输,于是网景公司设计了SSL(Secure Sockets Layer)协议用于对HTTP协议传输的数据进行加密,从而就诞生了HTTPS。

简单来说,HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,要比HTTP协议安全

总结两者主要的区别如下所示:

1、https协议需要到ca申请证书,一般免费证书较少,因而需要一定费用。

2、http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议

3、http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443

4、http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。

HTTP1.0 和 HTTP1.1之间的区别

1. 长连接(Persistent Connection)
HTTP1.1支持长连接和请求的流水线处理,在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟,在HTTP1.1中默认开启长连接keep-alive,一定程度上弥补了HTTP1.0每次请求都要创建连接的缺点。HTTP1.0需要使用keep-alive参数来告知服务器端要建立一个长连接。

2. 节约带宽
HTTP1.0中存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能。HTTP1.1支持只发送header信息(不带任何body信息),如果服务器认为客户端有权限请求服务器,则返回100,客户端接收到100才开始把请求body发送到服务器;如果返回401,客户端就可以不用发送请求body了节约了带宽。

3. HOST域
在HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名(hostname),HTTP1.0没有host域。随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。HTTP1.1的请求消息和响应消息都支持host域,且请求消息中如果没有host域会报告一个错误(400 Bad Request)。

4. 缓存处理
在HTTP1.0中主要使用header里的If-Modified-Since,Expires来做为缓存判断的标准,HTTP1.1则引入了更多的缓存控制策略例如Entity tag,If-Unmodified-Since, If-Match, If-None-Match等更多可供选择的缓存头来控制缓存策略。

5. 错误通知的管理
在HTTP1.1中新增了24个错误状态响应码,

以上是关于计算机网络面试题汇总的主要内容,如果未能解决你的问题,请参考以下文章

Java加pring面试题汇总

经典Java面试题汇总及答案解析

计算机网络面试题汇总

Java经典面试题汇总网络编程

计算机网络-面试题汇总

覆盖90%面试! 2020最新Netty面试题汇总