计算机网络面试题(二)
● 请问TCP三次握手是怎样的?
参考回答:
2.服务器收到syn0,回复syn1,ack(syn0+1)
3.客户端收到syn1,回复ack(syn1+1)
● 请问tcp握手为什么两次不可以?为什么不用四次?
参考回答:
不用四次:
本来握手应该和挥手一样都是需要确认两个方向都能联通的,本来模型应该是:
1.客户端发送syn0给服务器
2.服务器收到syn0,回复ack(syn0+1)
3.服务器发送syn1
4.客户端收到syn1,回复ack(syn1+1)
因为tcp是全双工的,上边的四部确认了数据在两个方向上都是可以正确到达的,但是2,3步没有没有上下的联系,可以将其合并,加快握手效率,所有就变成了3步握手。
● 请你来说一下TCP拥塞控制?
参考回答:
过程cwnd的大小呈指数增长,直到超过慢启动门限,然后进入拥塞避免阶段,cwnd的大小线性增长,当出现网络拥塞(三个重复的ack或者超时)时候,将慢启动门限设置为出现拥塞时候大小的一半,cwnd的大小重新从0开始进入慢启动阶段。
快重传和快恢复:快重传要求接收方在收到一个失序的报文段后就立即发出重复确认(为的是使发送方及早知道有报文段没有到达对方)而不要等到自己发送数据时捎带确认。快重传算法规定,发送方只要一连收到三个重复确认就应当立即重传对方尚未收到的报文段,而不必继续等待设置的重传计时器时间到期
● TCP和UDP的区别和各自适用的场景
参考回答:
1) 连接
TCP是面向连接的传输层协议,即传输数据之前必须先建立好连接。
UDP无连接。
2) 服务对象
TCP是点对点的两点间服务,即一条TCP连接只能有两个端点;
UDP支持一对一,一对多,多对一,多对多的交互通信。
3) 可靠性
TCP是可靠交付:无差错,不丢失,不重复,按序到达。
UDP是尽最大努力交付,不保证可靠交付。
4)拥塞控制,流量控制
TCP有拥塞控制和流量控制保证数据传输的安全性。
UDP没有拥塞控制,网络拥塞不会影响源主机的发送效率。
5) 报文长度
TCP是动态报文长度,即TCP报文长度是根据接收方的窗口大小和当前网络拥塞情况决定的。
UDP面向报文,不合并,不拆分,保留上面传下来报文的边界。
6) 首部开销
TCP首部开销大,首部20个字节。
UDP首部开销小,8字节。(源端口,目的端口,数据长度,校验和)
2)TCP和UDP适用场景
从特点上我们已经知道,TCP 是可靠的但传输速度慢,UDP 是不可靠的但传输速度快。因此在选用具体协议通信时,应该根据通信数据的要求而决定。
若通信数据完整性需让位与通信实时性,则应该选用TCP 协议(如文件传输、重要状态的更新等);反之,则使用 UDP 协议(如视频传输、实时通信等)。
● 请你来说一下TCP三次握手四次挥手的过程,为什么tcp连接握手需要三次, time_wait状态
参考回答:
客户端A:发送SYN连接报文,序列号为x,进入SYNC-SENT状态。
服务端B:发送SYN连接确认报文(SYN=1,ACK = 1),序列号为y(seq = y),确认报文x(ack = x + 1),进入SYNC-RCVD状态。
客户端A:发送ACK确认报文(ACK = 1),序列号为x+1(seq = x + 1),确认报文y+1(ack = y + 1),进入ESTABLISHED状态。
服务器B:收到后进入ESTABLISHED状态。
2)三次握手原因:
三次握手是为了防止,客户端的请求报文在网络滞留,客户端超时重传了请求报文,服务端建立连接,传输数据,释放连接之后,服务器又收到了客户端滞留的请求报文,建立连接一直等待客户端发送数据。
服务器对客户端的请求进行回应(第二次握手)后,就会理所当然的认为连接已建立,而如果客户端并没有收到服务器的回应呢?此时,客户端仍认为连接未建立,服务器会对已建立的连接保存必要的资源,如果大量的这种情况,服务器会崩溃。
3) TCP释放(四次分手)过程:
服务端A:发送FIN报文(FIN = 1),序列号为u(seq = u),进入FIN-WAIT 1状态。
客户端B:发送ACK确认报文(ACK = 1),序列号为v(seq = v),确认报文u(ack = u + 1),进入CLOSE-WAIT状态,继续传送数据。
服务端A:收到上述报文进入FIN-WAIT2状态,继续接受B传输的数据。
客户端B:数据传输完毕后,发送FIN报文(FIN = 1,ACK = 1),序列号为w(seq = w),确认报文u(ack = u + 1),进入LAST-ACK状态。
服务端A:发送ACK确认报文(ACK = 1),序列号为u+1(seq = u + 1),确认报文w(ack = w + 1),进入TIME-WAIT状态,等待2MSL(最长报文段寿命),进入CLOSED状态。
客户端B:收到后上述报文后进入CLOSED状态。
4)为什么TCP协议终止链接要四次?
1、当客户端确认发送完数据且知道服务器已经接收完了,想要关闭发送数据口(当然确认信号还是可以发),就会发FIN给服务器。
2、服务器收到客户端发送的FIN,表示收到了,就会发送ACK回复。
3、但这时候服务器可能还在发送数据,没有想要关闭数据口的意思,所以服务器的FIN与ACK不是同时发送的,而是等到服务器数据发送完了,才会发送FIN给客户端。
4、客户端收到服务器发来的FIN,知道服务器的数据也发送完了,回复ACK, 客户端等待2MSL以后,没有收到服务器传来的任何消息,知道服务器已经收到自己的ACK了,客户端就关闭链接,服务器也关闭链接了。
5)2MSL意义:
1、保证最后一次握手报文能到B,能进行超时重传。
2、2MSL后,这次连接的所有报文都会消失,不会影响下一次连接。
● 请你来说一说http协议
参考回答:
HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web)服务器传输超文本到本地浏览器的传送协议。
HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件,图片文件,查询结果等)。
HTTP是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展。目前在WWW中使用的是HTTP/1.0的第六版,HTTP/1.1的规范化工作正在进行之中,而且HTTP-NG(Next Generation of HTTP)的建议已经提出。
HTTP协议工作于客户端-服务端架构为上。浏览器作为HTTP客户端通过URL向HTTP服务端即WEB服务器发送所有请求。Web服务器根据接收到的请求后,向客户端发送响应信息。
2)HTTP协议特点
1、简单快速:
客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。
2、灵活:
HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
3、无连接:
无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
4、无状态:
HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
5、支持B/S及C/S模式。
6、默认端口80
7、基于TCP协议
3)HTTP过程概述:
HTTP协议定义Web客户端如何从Web服务器请求Web页面,以及服务器如何把Web页面传送给客户端。HTTP协议采用了请求/响应模型。客户端向服务器发送一个请求报文,请求报文包含请求的方法、URL、协议版本、请求头部和请求数据。服务器以一个状态行作为响应,响应的内容包括协议的版本、成功或者错误代码、服务器信息、响应头部和响应数据。
HTTP 请求/响应的步骤如下:
1、客户端连接到Web服务器
一个HTTP客户端,通常是浏览器,与Web服务器的HTTP端口(默认为80)建立一个TCP套接字连接。例如,http://www.baidu.com。
2、发送HTTP请求
通过TCP套接字,客户端向Web服务器发送一个文本的请求报文,一个请求报文由请求行、请求头部、空行和请求数据4部分组成。
3、服务器接受请求并返回HTTP响应
Web服务器解析请求,定位请求资源。服务器将资源复本写到TCP套接字,由客户端读取。一个响应由状态行、响应头部、空行和响应数据4部分组成。
4、释放连接TCP连接
若connection 模式为close,则服务器主动关闭TCP连接,客户端被动关闭连接,释放TCP连接;若connection 模式为keepalive,则该连接会保持一段时间,在该时间内可以继续接收请求;
5、客户端浏览器解析HTML内容
客户端浏览器首先解析状态行,查看表明请求是否成功的状态代码。然后解析每一个响应头,响应头告知以下为若干字节的HTML文档和文档的字符集。客户端浏览器读取响应数据HTML,根据HTML的语法对其进行格式化,并在浏览器窗口中显示。
4、举例:
在浏览器地址栏键入URL,按下回车之后会经历以下流程:
1、浏览器向 DNS 服务器请求解析该 URL 中的域名所对应的 IP 地址;
2、解析出 IP 地址后,根据该 IP 地址和默认端口80,和服务器建立TCP连接;
3、浏览器发出读取文件(URL中域名后面部分对应的文件)的HTTP 请求,该请求报文作为 TCP 三次握手的第三个报文的数据发送给服务器;
4、服务器对浏览器请求作出响应,并把对应的 html 文本发送给浏览器;
5、释放 TCP连接;
6、浏览器将该 html 文本并显示内容;
● 请你来说一下GET和POST的区别
参考回答:
对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);
而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)
2、区别:
1、get参数通过url传递,post放在request body中。
2、get请求在url中传递的参数是有长度限制的,而post没有。
3、get比post更不安全,因为参数直接暴露在url中,所以不能用来传递敏感信息。
4、get请求只能进行url编码,而post支持多种编码方式。
5、get请求会浏览器主动cache,而post支持多种编码方式。
6、get请求参数会被完整保留在浏览历史记录里,而post中的参数不会被保留。
7、GET和POST本质上就是TCP链接,并无差别。但是由于HTTP的规定和浏览器/服务器的限制,导致他们在应用过程中体现出一些不同。
8、GET产生一个TCP数据包;POST产生两个TCP数据包。
● 请你来说一下socket编程中服务器端和客户端主要用到哪些函数
参考回答:
1、服务器端程序:
1创建一个socket,用函数socket()
2绑定IP地址、端口等信息到socket上,用函数bind()
3设置允许的最大连接数,用函数listen()
4接收客户端上来的连接,用函数accept()
5收发数据,用函数send()和recv(),或者read()和write()
6关闭网络连接
2、客户端程序:
1创建一个socket,用函数socket()
2设置要连接的对方的IP地址和端口等属性
3连接服务器,用函数connect()
4收发数据,用函数send()和recv(),或read()和write()
5关闭网络连接
2)基于UDP的socket:
1、服务器端流程
1建立套接字文件描述符,使用函数socket(),生成套接字文件描述符。
2设置服务器地址和侦听端口,初始化要绑定的网络地址结构。
3绑定侦听端口,使用bind()函数,将套接字文件描述符和一个地址类型变量进行绑定。
4接收客户端的数据,使用recvfrom()函数接收客户端的网络数据。
5向客户端发送数据,使用sendto()函数向服务器主机发送数据。
6关闭套接字,使用close()函数释放资源。UDP协议的客户端流程
2、客户端流程
1建立套接字文件描述符,socket()。
2设置服务器地址和端口,struct sockaddr。
3向服务器发送数据,sendto()。
4接收服务器的数据,recvfrom()。
5关闭套接字,close()。
● 请你来说一下数字证书是什么,里面都包含那些内容
参考回答:
数字证书是数字证书在一个身份和该身份的持有者所拥有的公/私钥对之间建立了一种联系,由认证中心(CA)或者认证中心的下级认证中心颁发的。根证书是认证中心与用户建立信任关系的基础。在用户使用数字证书之前必须首先下载和安装。
认证中心是一家能向用户签发数字证书以确认用户身份的管理机构。为了防止数字凭证的伪造,认证中心的公共密钥必须是可靠的,认证中心必须公布其公共密钥或由更高级别的认证中心提供一个电子凭证来证明其公共密钥的有效性,后一种方法导致了多级别认证中心的出现。
2)数字证书颁发过程:
数字证书颁发过程如下:用户产生了自己的密钥对,并将公共密钥及部分个人身份信息传送给一家认证中心。认证中心在核实身份后,将执行一些必要的步骤,以确信请求确实由用户发送而来,然后,认证中心将发给用户一个数字证书,该证书内附了用户和他的密钥等信息,同时还附有对认证中心公共密钥加以确认的数字证书。当用户想证明其公开密钥的合法性时,就可以提供这一数字证书。
3)内容:
数字证书的格式普遍采用的是X.509V3国际标准,一个标准的X.509数字证书包含以下一些内容:
1、证书的版本信息;
2、证书的序列号,每个证书都有一个唯一的证书序列号;
3、证书所使用的签名算法;
4、证书的发行机构名称,命名规则一般采用X.500格式;
5、证书的有效期,通用的证书一般采用UTC时间格式;
6、证书所有人的名称,命名规则一般采用X.500格式;
7、证书所有人的公开密钥;
8、证书发行者对证书的签名。
● 请你来介绍一下udp的connect函数
参考回答:
对于已连接UDP套接字,与默认的未连接UDP套接字相比,发生了三个变化。
其实一旦UDP套接字调用了connect系统调用,那么这个UDP上的连接就变成一对一的连接,但是通过这个UDP连接传输数据的性质还是不变的,仍然是不可靠的UDP连接。一旦变成一对一的连接,在调用系统调用发送和接受数据时也就可以使用TCP那一套系统调用了。
1、我们再也不能给输出操作指定目的IP地址和端口号。也就是说,我们不使用sendto,而改用write或send。写到已连接UDP套接字上的任何内容都自动发送到由connect指定的协议地址。可以给已连接的UDP套接字调用sendto,但是不能指定目的地址。sendto的第五个参数必须为空指针,第六个参数应该为0.
2、不必使用recvfrom以获悉数据报的发送者,而改用read、recv或recvmsg。在一个已连接UDP套接字上,由内核为输入操作返回的数据报只有那些来自connect指定协议地址的数据报。这样就限制一个已连接UDP套接字能且仅能与一个对端交换数据报。
3、由已连接UDP套接字引发的异步错误会返回给它们所在的进程,而未连接的UDP套接字不接收任何异步错误。
来自任何其他IP地址或断开的数据报不投递给这个已连接套接字,因为它们要么源IP地址要么源UDP端口不与该套接字connect到的协议地址相匹配。
UDP客户进程或服务器进程只在使用自己的UDP套接字与确定的唯一对端进行通信时,才可以调用connect。调用connect的通常是UDP客户,不过有些网络应用中的UDP服务器会与单个客户长时间通信TFTP,这种情况下,客户和服务器都可能调用connect。
● 请你讲述一下TCP三次握手,四次挥手,以及为什么用三次握手?
参考回答:
1.客户端发送syn0给服务器
2.服务器收到syn0,回复syn1,ack(syn0+1)
3.客户端收到syn1,回复ack(syn1+1)
四次挥手(这里以客户端主动断开为例)
1.客户端发送fin
2.服务端收到fin,回复ack,然后服务器去处理其他事
3.服务器事情处理完,回复fin
4.客户端回复ack
为什么用三次握手
本来握手应该和挥手一样都是需要确认两个方向都能联通的,本来模型应该是:
1.客户端发送syn0给服务器
2.服务器收到syn0,回复ack(syn0+1)
3.服务器发送syn1
3.客户端收到syn1,回复ack(syn1+1)
因为tcp是全双工的,上边的四部确认了数据在两个方向上都是可以正确到达的,但是2,3步没有没有上下的联系,可以将其合并,加快握手效率,所有就变成了3步握手。
● 请你说一下阻塞,非阻塞,同步,异步
参考回答:
同步和异步:调用者必须循环自去查看事件有没有发生,这种情况是同步。调用者不用自己去查看事件有没有发生,而是等待着注册在事件上的回调函数通知自己,这种情况是异步
● 请你讲述一下Socket编程的send() recv() accept() socket()函数?
参考回答:
recv函数用来从TCP连接的另一端接收数据,当应用程序调用recv函数时,recv先等待s的发送缓冲中的数据被协议传送完毕,然后从缓冲区中读取接收到的内容给应用层。
accept函数用了接收一个连接,内核维护了半连接队列和一个已完成连接队列,当队列为空的时候,accept函数阻塞,不为空的时候accept函数从上边取下来一个已完成连接,返回一个文件描述符。
● 请你说一下http协议会话结束标志怎么截出来?
参考回答:
● 请你说一说三次握手
参考回答:
3.客户端收到syn1,回复ack(syn1+1)
● 请你说一说四次挥手
参考回答:
3.服务器发送syn1
4.客户端收到syn1,回复ack(syn1+1)