牛客网:C++面试宝典——计算机网络(1):TCP握手挥手,http与https,中断
● 请你说一下TCP怎么保证可靠性,并且简述一下TCP建立连接和断开连接的过程
1.可靠性
1)***、确认应答、超时重传
数据到达接收方,接收方需要发出一个确认应答,表示已经收到该数据段,并且确认序号会说明了它下一次需要接收的数据***。如果发送发迟迟未收到确认应答,那么可能是发送的数据丢失,也可能是确认应答丢失,这时发送方在等待一定时间后会进行重传。这个时间一般是2*RTT(报文段往返时间)+一个偏差值。
2)窗口控制与高速重发控制/快速重传(重复确认应答)
TCP会利用窗口控制来提高传输速度,意思是在一个窗口大小内,不用一定要等到应答才能发送下一段数据,窗口大小就是无需等待确认而可以继续发送数据的最大值。如果不使用窗口控制,每一个没收到确认应答的数据都要重发。
使用窗口控制,如果数据段1001-2000丢失,后面数据每次传输,确认应答都会不停地发送序号为1001的应答,表示我要接收1001开始的数据,发送端如果收到3次相同应答,就会立刻进行重发;但还有种情况有可能是数据都收到了,但是有的应答丢失了,这种情况不会进行重发,因为发送端知道,如果是数据段丢失,接收端不会放过它的,会疯狂向它提醒......
3)拥塞控制
如果把窗口定的很大,发送端连续发送大量的数据,可能会造成网络的拥堵,甚至造成网络的瘫痪。所以TCP在为了防止这种情况而进行了拥塞控制。
在发送数据之前,首先将拥塞窗口与接收窗口大小比对,取较小的值作为实际发送的窗口。
慢启动:定义拥塞窗口,一开始将该窗口大小设为1,之后每次收到确认应答(经过一个rtt),将拥塞窗口大小*2。
拥塞避免是指当拥塞窗口大小达到这个阈值,拥塞窗口的值不再指数上升,而是线性的增长(每次确认应答/每个rtt,拥塞窗口大小+1),以此来避免拥塞。
将报文段的超时重传看做拥塞,则一旦发生超时重传,我们需要先将阈值设为当前窗口大小的一半,并且将窗口大小设为初值1,然后重新进入慢启动过程。
快重传:在遇到3次重复确认应答(高速重发控制)时,代表收到了3个报文段,但是这之前的1个段丢失了,便对它进行立即重传。
快恢复:更新阈值和拥塞窗口为当前窗口的一半
2.建立连接:三次握手
1. Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。
2. Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。
3. Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给Server,Server检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。
TCP是一种可靠传输协议,既要保证数据的可靠传输,又要提高传输效率。
3次握手完成两个重要的功能,既要双方做好发送数据的准备工作(双方都知道彼此已准备好),也要允许双方就初始***进行协商,这个***在握手过程中被发送和确认。
四次握手是浪费的
两次的话:----> SYN=1, seq=x
<----- SYN=1, ACK=1, seq=y,ack=x+1
a和b就a的初始***达成一致,但是并没有就b的***达成一致
B如果没有收到A的ACK,会超时重传自己的SYN同步信号,一直到收到A的ACK为止。
3.断开连接
1.数据传输结束后,客户端的应用进程发出连接释放报文段,并停止发送数据,客户端进入FIN_WAIT_1状态,此时客户端依然可以接收服务器发送来的数据。
2.服务器接收到FIN后,发送一个ACK给客户端,确认序号为收到的序号+1,服务器进入CLOSE_WAIT状态。客户端收到后进入FIN_WAIT_2状态。
3.当服务器没有数据要发送时,服务器发送一个FIN报文,此时服务器进入LAST_ACK状态,等待客户端的确认
4.客户端收到服务器的FIN报文后,给服务器发送一个ACK报文,确认***为收到的序号+1。此时客户端进入TIME_WAIT状态,等待2MSL(MSL:报文段最大生存时间),然后关闭连接。
服务器只要收到了客户端发出的确认,立即进入CLOSED状态。
可以看到,服务器结束TCP连接的时间要比客户端早一些。
由于TCP连接时全双工的,因此,每个方向都必须要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个FIN来终止这一方向的连接,
【问题2】为什么连接的时候是三次握手,关闭的时候却是四次握手?
因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的
但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。
【问题3】为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?
虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是我们必须假象网络是不可靠的,有可以最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。在Client发送出最后的ACK回复,但该ACK可能丢失。Server如果没有收到ACK,将不断重复发送FIN片段。所以Client不能立即关闭,它必须确认Server接收到了该ACK。Client会在发送出ACK之后进入到TIME_WAIT状态。Client会设置一个计时器,等待2MSL的时间。如果在该时间内再次收到FIN,那么Client会重发ACK并再次等待2MSL。
2MSL就是一个发送和一个回复所需的最大时间。
【问题4】如果已经建立了连接,但是客户端突然出现故障了怎么办?
TCP还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。
● 请回答一下HTTP和HTTPS的区别,以及HTTPS有什么缺点?
Http:超文本传输协议是互联网上应用最为广泛的一种网络协议。
Https:是以安全为目标的Http通道,是Http的安全版。Https的安全基础是SSL。
HTTP协议和HTTPS协议区别如下: 参考
(1)http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。
(2)https协议需要到ca机构申请ssl证书
(3)HTTP协议端口是80,HTTPS协议端口是443
(4)http的连接很简单,是无状态的。Https协议是由SSL+Http协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。
HTTPS优点:
HTTPS传输数据过程中使用**进行加密,所以安全性更高(可防止数据在传输过程中不被窃取、修改,确保数据的完整性。)
HTTPS协议可以认证用户和服务器,确保数据发送到正确的用户和服务器
HTTPS缺点:
HTTPS握手阶段延时较高:由于在进行HTTP会话之前还需要进行SSL握手,因此HTTPS协议握手阶段延时增加
HTTPS部署成本高:一方面HTTPS协议需要使用证书来验证自身的安全性,所以需要购买CA证书;另一方面由于采用HTTPS协议需要进行加解密的计算,占用一定的计算资源和服务器成本。
● 请你说一说HTTP返回码 参考
1xx(临时响应):表示临时响应并需要请求者继续执行操作的状态代码。
100(继续)
101(切换协议)请求者已要求服务器切换协议,服务器已确认并准备切换。
200(成功)服务器已成功处理了请求。通常,这表示服务器提供了请求的网页。
206 部分内容 服务器成功执行了部分请求
3xx (重定向):表示要完成请求,需要进一步操作。 通常,这些状态代码用来重定向。
4xx(请求错误):客户端错误--请求有语法错误或请求无法实现
5xx(服务器错误):表示服务器在尝试处理请求时发生内部错误。 这些错误可能是服务器本身的错误,而不是请求出错。
● 请你说一说IP地址作用,以及MAC地址作用
iP地址是IP协议提供的一种统一的地址格式,为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异。
IP地址专注于网络层,网络层设备(如路由器)根据IP地址,将数据包从一个网络传递转发到另外一个网络上;
而MAC地址专注于数据链路层,数据链路层设备(如交换机)根据MAC地址,将一个数据帧从一个节点传送到相同链路的另一个节点上。MAC地址是一个硬件地址,用来定义网络设备的位置,主要由数据链路层负责
IP和MAC地址这种映射关系由ARP(Address Resolution Protocol,地址解析协议)协议完成
● 请介绍一下操作系统中的中断
中断是指CPU对系统发生的某个事件做出的一种反应,CPU暂停正在执行的程序,保存现场后自动去执行相应的处理程序,处理完该事件后再返回中断处继续执行原来的程序。
中断一般三类,
一种是由CPU外部引起的,如I/O中断、时钟中断,
一种是来自CPU内部事件或程序执行中引起的中断,例如程序非法操作,地址越界、浮点溢出),
最后一种是在程序中使用了系统调用引起的。
而中断处理一般分为中断响应和中断处理两个步骤,中断响应由硬件实施,中断处理主要由软件实施。
● 请回答OSI七层模型和TCP/IP四层模型,每层列举2个协议
OSI七层
物理层: 通过媒介传输比特,确定机械及电气规范,传输单位为bit,主要包括的协议为:IEE802.3 CLOCK
数据链路层:将比特组装成帧和点到点的传递,传输单位为帧,主要包括的协议为MAC VLAN PPP
介质访问和链路管理
网络层:负责数据包从源到宿的传递和网际互连,传输单位为包,主要包括的协议为IP ARP ICMP
进行逻辑地址寻址,实现不同网络之间的路径选择
传输层:提供端到端的可靠报文传递和错误恢复,传输单位为报文,主要包括的协议为TCP UDP
会话层:建立、管理和终止会话,传输单位为SPDU,主要包括的协议为RPC NFS
表示层: 对数据进行翻译、加密和压缩,传输单位为PPDU,主要包括的协议为JPEG ASCII
应用层: 允许访问OSI环境的手段,传输单位为APDU,主要包括的协议为FTP HTTP DNS SMTP
网络服务与最终用户的一个接口。
TCP/IP四层模型:参考
网络接口层:以太网中的数据链路层进行通信,
这是TCP/IP软件的最低层,负责接收IP数据包并通过网络发送之,或者从网络上接收物理帧,抽出IP数据报,交给IP层。MAC VLAN
网络层:负责点到点(point-to-point)的传输(这里的"点"指主机或路由器)主要定义了IP地址格式,使得不同应用类型的数据在Internet上传输。提供基本的数据封包传送功能,让每一块数据包都能够到达目的主机(但不检查是否被正确接收),如网际协议(IP,ICMP,ARP)
传输层:提供端到端(end-to-end)的传输(这里的"端"指源主机到目标主机) 在此层中,它提供了节点间的数据传送服务,如传输控制协议(TCP)、用户数据报协议(UDP)等,
应用层 应用程序间沟通的层,如简单电子邮件传输(SMTP)文件传输协议(FTP)网络远程访问协议(Telnet)域名解析协议(DNS)等
● 搜索baidu,会用到计算机网络中的什么层?每层是干什么的
浏览器中输入URL 统一资源定位标志
浏览器要将URL解析为IP地址,解析域名就要用到DNS协议,首先主机会查询DNS的缓存,如果没有就给本地DNS发送查询请求。DNS查询分为两种方式,一种是递归查询,一种是迭代查询。如果是迭代查询,本地的DNS服务器,向根域名服务器发送查询请求,根域名服务器告知该域名的一级域名服务器,然后本地服务器给该一级域名服务器发送查询请求,然后依次类推直到查询到该域名的IP地址。DNS服务器是基于UDP的,因此会用到UDP协议。
得到IP地址后,浏览器就要与服务器建立一个http连接。因此要用到http协议。
http生成一个get请求报文,将该报文传给TCP层处理,所以还会用到TCP协议。如果采用https还会使用https协议先对http数据进行加密。
TCP层如果有需要先将HTTP数据包分片,TCP的数据包然后会发送给IP层,用到IP协议。
在一个网段内的寻址是通过以太网协议实现(也可以是其他物理层协议,比如PPP,SLIP),以太网协议需要知道目的IP地址的物理地址,又需要ARP协议。
1、DNS协议,http协议,https协议属于应用层
应用层确定进程之间通信的性质以满足用户的需要。这里的进程就是指正在运行的程序。
2、TCP/UDP属于传输层
传输层的任务就是负责主机中两个进程之间的通信。即面向连接的传输控制协议TCP,和无连接的用户数据报协议UDP。面向连接的服务能够提供可靠的交付,但无连接服务则不保证提供可靠的交付,它只是“尽最大努力交付”。这两种服务方式都很有用,备有其优缺点。在分组交换网内的各个交换结点机都没有传输层。
3、IP协议,ARP协议属于网络层
网络层负责为分组交换网上的不同主机提供通信。网络层的另一个任务就是要选择合适的路由,使源主机运输层所传下来的分组能够交付到目的主机。
4.数据链路层
当发送数据时,数据链路层的任务是将在网络层交下来的IP数据报组装成帧,在两个相邻结点间的链路上传送以帧为单位的数据。
5、物理层
物理层的任务就是透明地传送比特流。在物理层上所传数据的单位是比特。传递信息所利用的一些物理媒体,如双绞线、同轴电缆、光缆等,并不在物理层之内而是在物理层的下面。因此也有人把物理媒体当做第0层。
● 请你说一说TCP拥塞控制?以及达到什么情况的时候开始减慢增长的速度?
拥塞控制是防止过多的数据注入网络,使得网络中的路由器或者链路过载。流量控制是点对点的通信量控制,而拥塞控制是全局的网络流量整体性的控制。发送双方都有一个拥塞窗口——cwnd。
1、慢开始
最开始发送方的拥塞窗口为1,由小到大逐渐增大发送窗口和拥塞窗口。每经过一个传输轮次,拥塞窗口cwnd加倍。当cwnd超过慢开始门限,则使用拥塞避免算法,避免cwnd增长过大。
2、拥塞避免
每经过一个往返时间RTT,cwnd就增长1。
在慢开始和拥塞避免的过程中,一旦发现网络拥塞,就把慢开始门限设为当前值的一半,并且重新设置cwnd为1,重新慢启动。
4、快恢复
当发送方连续收到了三个重复确认,就乘法减半(慢开始门限减半),将当前的cwnd设置为慢开始门限,并且采用拥塞避免算法
达到什么情况的时候开始减慢增长的速度?
采用慢开始和拥塞避免算法的时候
1. 一旦cwnd>慢开始门限,就采用拥塞避免算法,减慢增长速度
2. 一旦出现丢包的情况,就重新进行慢开始,减慢增长速度
采用快恢复和快重传算法的时候
1. 一旦cwnd>慢开始门限,就采用拥塞避免算法,减慢增长速度
2. 一旦发送方连续收到了三个重复确认,就采用拥塞避免算法,减慢增长速度
● 请你说说TCP/IP数据链路层的交互过程
网络层等在数据链路层用MAC地址作为通信目标,数据包到达网络层等往数据链路层发送的时候,首先回去ARP缓存表去查找ip对应的MAC地址,如果查到了,就将此ip对应的MAC地址封装到链路层数据包的包头。如果缓存中没有找到,则会发起一个广播,who is ip xxx tell ip xxxx,所有收到广播的机器看到这个ip是不是自己的,如果是自己的,则以单播的形式将自己的mac地址回复给请求机器。
● 请你说说传递到IP层怎么知道报文该给哪个应用程序,它怎么区分UDP报文还是TCP报文
根据端口区分;
看ip头中的协议标识字段,17是udp,6是tcp
● 请问你有没有基于做过socket的开发?具体网络层的操作该怎么做?(其实也是问网络编程的基本步骤)
TCP:
server:socket->bind->listen->accept
client:socket->connect
server:
1创建一个socket,用函数socket()
2绑定IP地址、端口等信息到socket上,用函数bind()
3监听连接,表明它愿意接收连接─用函数listen()
4接收客户端上来的连接,用函数accept()
(5收发数据,用函数send()和recv(),或者read()和write())
client:
1创建一个socket,用函数socket()
2.connect()用于建立连接,连接服务器
UDP:
server:socket->bind->recvfrom
client:socket->connect
server:
1.建立套接字文件描述符,使用函数socket(),
2.绑定侦听端口,使用bind()函数,将套接字文件描述符和一个地址类型变量进行绑定。
3.接收客户端的数据,使用recvfrom()函数接收客户端的网络数据。
4.向客户端发送数据,使用sendto()函数向服务器主机发送数据。
client:
socket->sendto->recvfrom
● 请问server端监听端口,但还没有客户端连接进来,此时进程处于什么状态?
参考回答:
这个需要看服务端的编程模型,如果如上一个问题的回答描述的这样,则处于阻塞状态,如果使用了epoll,select等这样的io复用情况下,处于运行状态