其他计算机网络面试题总结:
【计算机网络重要知识点总结二】
【计算机网络重要知识点总结三】
【计算机网络重要知识点总结四】
一、OSI七层模型和TCP/IP四层模型?每一层作用及常用协议?
1.OSI七层模型
- 应用层:为计算机提供服务。
- 表示层:数据处理,加密解密、压缩解压缩。
- 会话层:管理应用程序间的会话。
- 传输层:为两台主机进程之间的通信提供数据传输服务。
- 网络层:选择合适的路由和交换节点,确保数据及时传送。
- 数据链路层:将网络层传递下来的IP数据包组装成帧,在相邻节点的链路上传送帧。
- 物理层:实现相邻节点间比特流的透明传输,尽可能屏蔽传输介质和物理设备的差异。
2.TCP/IP四层模型
- 应用层:常用协议DNS,HTTP,SMTP(电子邮件传输)
- 传输层:TCP,UDP
- 网络层:IP协议
- 网络接口层
二、TCP三次握手和四次挥手?
三次握手
1.过程?
- 第一次握手:客户端随机初始化一个起始序列号x,在该报文首部中设置序列号
seq=x
,标志位SYN=1
,表示SYN报文。将此报文发送给服务端,表示发起连接。该报文不包含应用层数据。 - 第二次握手:服务端收到报文后,也随机初始化一个起始序列号y,在该报文首部中设置序列号
seq=y
,确认序列号ack=x+1
,标志位SYN=1,ACK=1
。该报文不包含应用层数据。 - 第三次握手:客户端收到报文后,需回应最后一个应答报文。在该报文中,设置序列号
seq=x+1
,确认序列号ack=y+1
,标志位ACK=1
。该报文可以携带数据。
标志位SYN=1表示希望发起连接,ACK=1表示确认序列号有效。
2.每次握手后客户端和服务器的状态?
如图:
3.为什么不是两次、四次握手?
- 三次握手可以阻止重复历史连接的初始化(主要原因)
- 三次握手可以同步双方的初始序列号
- 三次握手可以避免浪费资源
序列号的作用:
- 接收方去除重复的数据
- 接收方可以按顺序接收数据包
- 标识发送过的数据包哪些已被对方收到(ACK标志位)
4.握手过程中数据包丢失会发生什么?
第一次握手丢失?
如果客户端迟迟收不到服务端的 SYN-ACK 报文(第二次握手),就会触发「超时重传」机制,重传 SYN 报文。
在linux中,重传次数由内核参数控制,一般是5,每次超时重传的时间是上一次的两倍。
第二次握手丢失?
第二次握手的 SYN-ACK
报文其实有两个目的 :
- ACK,对第一次握手的确认报文
- SYN,服务端发起建立连接的报文
ACK(客户端):如果客户端迟迟没有收到第二次握手,那么客户端就觉得可能自己的 SYN 报文(第一次握手)丢失了,于是客户端就会触发超时重传机制,重传 SYN 报文。
SYN(服务端):第二次握手丢失,服务端就收不到第三次握手,于是服务端这边会触发超时重传机制,重传 SYN-ACK 报文。
第三次握手丢失?
如果服务端那一方迟迟收不到这个确认报文,就会触发超时重传机制,重传 SYN-ACK 报文,直到收到第三次握手,或者达到最大重传次数。
ACK 报文是不会有重传的,当 ACK 丢失了,就由对方重传对应的报文。
四次挥手
1.过程?
- 客户端打算关闭连接,发送一个
FIN=1
的FIN报文给服务端 - 服务端收到该报文后,向客户端发送
ACK=1
的ACK报文 - 等待服务端处理完数据之后,向客户端发送
FIN=1
的FIN报文 - 客户端收到服务端的FIN报文后,回应一个ACK报文
2.每个挥手过程的状态?
3.为什么挥手需要四次?
服务端通常需要等待完成数据的发送和处理,所以服务端的 ACK
和 FIN
一般都会分开发送,从而比三次握手导致多了一次。
4.挥手过程中数据包丢失会发生什么?
第一次挥手丢失?
客户端没有收到ACK,所以客户端重传FIN报文。
第二次挥手丢失?
ACK报文不会重传,客户端未收到ACK,仍然会重传FIN报文。
第三次挥手丢失?
服务端未收到ACK,所以服务端重传FIN报文。
第四次挥手丢失?
ACK报文不会重传,服务端未收到ACK,仍然会重传FIN报文。
5.为什么需要TIME_WAIT 状态?
- 防止历史连接中的数据,被后面相同四元组的连接错误的接收
- 保证「被动关闭连接」的一方,能被正确的关闭
6.为什么TIME_WAIT 等待的时间是 2MSL?
MSL是指报文最大生存时间。
-
网络中可能存在来自发送方的数据包,当这些发送方的数据包被接收方处理后又会向对方发送响应,所以一来一回需要等待 2 倍的时间。
-
2MSL时长 这其实是相当于至少允许报文丢失一次。比如 ACK 在一个 MSL 内丢失,这样被动方重发的 FIN 会在第 2 个 MSL 内到达,TIME_WAIT 状态的连接可以应对。
7.TIME_WAIT 状态会导致什么问题,怎么解决?
问题
在高并发短连接的 TCP 服务器上,当服务器处理完请求后主动请求关闭连接,这样服务器上会有大量的连接处于 TIME_WAIT 状态,服务器维护每一个连接需要一个 socket,也就是每个连接会占用一个文件描述符,而文件描述符的使用是有上限的,如果持续高并发,会导致一些正常的连接失败。
解决
修改配置或设置 SO_REUSEADDR 套接字,使得服务器处于 TIME-WAIT 状态下的端口能够快速回收和重用。
三、什么是SYN泛洪攻击?如何避免?
SYN攻击:
攻击者短时间伪造不同 IP 地址的 SYN
报文,服务端每接收到一个 SYN
报文,就进入SYN_RCVD
状态,但服务端发送出去的 ACK + SYN
报文,无法得到未知 IP 主机的 ACK
应答,久而久之就会占满服务端的半连接队列,使得服务器不能为正常用户服务。
如何避免:
(1)通过修改 Linux 内核参数,控制队列大小和当队列满时应做什么处理。
(2)当 「 SYN 队列」满之后,后续服务器收到 SYN 包,不进入「 SYN 队列」
- 计算出一个
cookie
值,再以 SYN + ACK 中的「序列号」返回客户端 - 收到ACK报文时,通过
cookie
检查该报文是否合法,如果合法直接放入Accept队列
全连接队列和半连接队列:
每一个
socket
执行listen
时,内核都会自动创建一个半连接队列和全连接队列。
- 半连接队列:也叫syn队列,存放尚未完成连接的socket,socket都处于
SYN_RECV
状态。半连接队列是个哈希表
,因为当第三次握手到来时,需要从半连接队列中取出对应ip端口的连接,使用哈希表就可以以O(1)的复杂度获得连接。- 全连接队列:也叫accept队列,存放已经完成连接的socket,socket都处于
ESTABLISHED
状态。全连接队列是个链表
,当通过accept获取连接的时候,并不需要关心具体是哪个连接,只要是个连接就行,所以从队头获得连接,复杂度为O(1)。在客户端发起第一次握手时,服务端会将其加入到syn队列中,并且响应客户端syn+ack报文,当收到客户端发送的ack应答报文(第三次握手)时,服务端将该连接(socket)从半连接队列中取出,加入到accept队列当中。等到进程调用accept时,将该连接取出来。
关于套接字socket:
以一个简单的程序为例,客户从键盘读取一行字符并发送给服务器,服务器将其转为大写后返回给客户,然后客户将修改后的数据打印出来。代码如下:
UDP
1.UDPClient.py
#可以使用服务器的ip地址(如128.138.32.126)或者主机名(如cis.poly.edu),如果使用主机名,则会根据DNS得到主机ip地址 serverName = 'hostname' #服务器端口号,客户端口号由操作系统分配 serverPort = 12000 #使用socket()方法创建一个socket,第一个参数标识该socket的地址簇(ipv4/ipv6),第二个参数标识该socket为UDP还是TCP clientSocket = socket(AF_INET,SOCK_DGRAM) message = raw_input('Input lowercase sentense:') #sendto()方法为报文附上目的地址(serverName,serverPort)后发送,源地址也会附加到报文上,不过这是自动完成的 clientSocket.sendto(message,(serverName,serverPort)) modifiedMessage,serverAddress = clientSocket.recvfrom(2048) print modifiedMessage clientSocket.close()
2.UDPServer.py
serverPort = 12000 serverSocket = socket(AF_INF,SOCK_DGRAM) #将端口与创建的套接字绑定 serverSocket.bind(('',serverPort)) print "server ready to receive" while true: #clientAddress获取客户端地址信息,方便回传 message,clientAddress = serverSocket.recvfrom(2048) modifiedMessage = message.upper() #给客户端发送信息的时候,服务器的地址也会附在分组上 serverSocket.sendto(modifiedMessage,clientAddress)
一个UDP套接字是由一个二元组来标识的,该二元组包括一个目的IP地址和一个目的端口号。
如果两个UDP报文段有不同的源IP地址或源端口号,但具有相同的目的IP地址和目的端口号,那么这两个报文段将通过相同的目的套接字被定向到相同的目的进程。
TCP
注意,TCP中用来监听(listen)的socket和传输数据的socket是两个socket!
1.TCPClient.py
serverName = 'servername' serverPort = 12000 clientSocket = socket(AF_INET,SOCK_STREAM) #发送之前先建立连接,参数为服务端IP地址和端口号 clientSocket.connect((serverName,serverPort)) sentence = raw_input('Input lowercase sentence:') #直接发送到连接中,不需要创建分组和附上目的地址 clientSocket.send(sentence) modifiedSentence = clientSocket.recv(1024) print 'From Server:',modifiedSentence clientSocket.close()
2.TCPServer.py
serverPort = 12000 serverSocket = socket(AF_INF,SOCK_DGRAM) serverSocket.bind(('',serverPort)) #监听套接字 serverSocket.listen(1) print "server ready to receive" while true: #获取连接 connectionSocket,addr = serverSocket.accept() sentence = connectionSocket.recv(1024) capitalizedSentence = sentence.upper() connectionSocket.send(capitalizedSentence) connectionSocket.close()
一个TCP套接字(连接)是由一个四元组标识的,包括:源IP地址、源端口号、目的IP地址、目的端口号。
当一个TCP报文段从网络到达一台主机时,该主机使用全部4个值来将报文段定向(分解)到相应的套接字,两个具有不同源IP地址或源端口号的报文段将被定向到两个不同的套接字。
四、什么是XSS攻击?如何避免?
也叫跨站脚本攻击,攻击者向有XSS漏洞的网站中输入恶意的 HTML /JS代码,当用户浏览该网站时,这段代码会自动执行,获取用户信息。
避免:
- 对标签进行过滤
- 表单数据对值的类型进行规定
五、什么是SQL注入?如何避免?
SQL注入就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。
避免:
- 使用预编译,进行参数绑定
- 使用正则表达式过滤传入的参数
六、URL和URI的区别?
URL:统一资源定位符,标识一个互联网资源,并指定对其进行操作或获取该资源的方法。
URI:统一资源标识符,URL 是 URI 的一个子集。
URI表示的是一个抽象的地址,URL表示的是一个详细的地址。两者都定义了资源是什么,而 URL 还定义了如何能访问到该资源。
抽象的地址:辽宁省大连市
详细的地址:辽宁省大连市高新园区软件园B2
七、什么是点对点和端对端?
点对点(数据链路层和网络层):基于MAC地址和或者IP地址,是指
一个设备发数据给与该这边直接连接的其他设备,通过一台一台直接相连的设备把数据传递到接收端
。
端对端(传输层):在两端设备间建立一条链路,忽略中间的设备,就像它们是直接相连的一样。链路建立后,发送端就可以发送数据,直至数据发送完毕,接收端确认接收成功。
八、TCP和UDP的区别及应用场景?
区别:
- TCP是可靠传输,UDP是不可靠传输
- TCP面向连接,UDP不面向连接
- TCP保证数据的有序性,UDP不保证数据的有序性
- TCP传输速度比UDP慢
- TCP有流量控制和拥塞控制,UDP没有
- TCP是重量级协议,首部长20字节,UDP是轻量级协议,首部短8字节
应用场景:
TCP:效率要求相对低,但对准确性要求相对高的场景。如文件传输(准确高要求高、但是速度可以相对慢)、接受邮件、远程登录。(HTTP、HTTPS、FTP(文件传输协议)、TELNET(远程登录服务协议)、SMTP(电子邮件传输协议))
UDP:效率要求相对高,对准确性要求相对低的场景。如QQ聊天、在线视频、网络语音电话(即时通讯,速度要求高,但是出现偶尔断续不是太大问题)。(DNS,RIP(路由信息协议),TFTP(简单文件传输协议))
九、什么是ARP协议?
地址解析协议。
解决了同一个局域网上的主机和路由器IP和MAC地址的解析。
十、什么是DHCP协议?
动态主机配置协议,是一个局域网的网络协议。
指的是由服务器控制一段IP地址范围,给用户提供即插即用的联网方式,用户不需要手动配置IP地址等信息。