链接:https://www.zhihu.com/question/28943943/answer/155660761
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
搞清这15个问题,那你就精通了TCP!
网络协议那么多,为什么面试喜欢问TCP?原因无外乎两个:
1、TCP协议直接与进程打交道,写网络程序要用;
2、TCP协议设计十分精巧,在一个不可靠的IP网络上实现了可靠传输,因为精巧,掌握TCP的原理自然也有难度,对它掌握如何,很能反映面试者的基础水平。闲言少叙,看看这几个问题你能不能答出来!
1、A进程通过TCP向另一台机器上的B进程发送了一个字符串“hello”,TCP返回对方成功接收的确认信息,请问,现在进程A是否可以肯定地说进程B收到了它发送的字符串?
答案:不能!举反例,进程B所在机器的TCP收到进程A发送的“hello”信息后,告诉进程A发送成功,但有可能没有立即将数据交给进程B,而是放在自己的缓冲区中,等待进程B读取,如果机器此时突然掉电,缓冲区中的信息将丢失,进程B将不可能收到“hello”字符串。
2、有什么办法来尽量避免上述情况的发生呢?
答案:将TCP报文段首部中的PSH标志置1,这样会让B端的TCP协议收到数据后尽快交给进程B,能不缓存尽量不要缓存。
3、我们知道通常TCP连接的建立需要3次握手,关闭需要4次握手,为什么关闭会多一次呢?
答案:简单说,就是TCP允许半关闭状态的存在。当进程A向进程B发送FIN,B也向A发送确认后。此时此刻的状态就是半关闭状态,A发送的FIN就是告诉B:“我要发送的数据都发送完了”但B没有发送FIN给A,有可能代表B还有没发送完的数据,如果B也发送完数据了,B就发送FIN给进程A,进程A确认B发送的FIN,这时,双方都已经发送完了数据,连接就断开了,TCP回收相关资源。
4、假如服务器突然掉电重启,但客户端并不知情,请问此时二者之间的TCP连接处于什么状态?
答案:处于半打开状态。就是客户端还觉得连接是正常的,服务器这边已经没有连接的任何信息了。
5、那么,假如此时客户端通过这个连接向服务器请求数据,服务器会怎么应对呢?
答案:服务器收到客户端的请求会进行一次ARP查询,获得客户端MAC地址,然而由于已经丢失了所有连接信息,此时的服务器是一脸懵逼(就像喝了孟婆汤!),于是乎,它会发一个RST给客户端,表示:“哥们,我不认识你,想跟我说话请先发送SYN!”
6、假如客户端按照服务器的要求重新建立连接,却搞错了服务器的端口号,会发生什么情况呢?
答案:有两种可能,一种是服务器端的TCP收到客户端请求,查看本机上是否有进程在监听相应的端口,如果有,就把请求交给这个进程,一般而言,这个进程不会接受这个连接的,于是它会发一个RST给客户端。还有一种可能是TCP没有找到哪个进程在监听相应的端口,于是TCP就会直接发一个RST给客户端,一般而言都会是这种情况。
7、假如现在有一个多进程服务器,服务器进程为A,接受一个连接后新建一个进程B来处理连接,再接受一个连接后又建一个进程C来处理这个连接,请问,进程ABC是否监听同样的端口?
答案:是!
8、那TCP接收到发送给这个端口的报文段,怎么决定发给哪个进程呢?
答案:首先,所有的SYN报文段都会发送给服务器进程A,其他的报文段依据<sourceIP:port,targetIP:port>这个四元组来决定发送给进程B还是进程C。
9、假如上面的服务器进程A收到一个连接请求,正在为这个请求创建处理进程的时候,又有新的连接请求进来了,TCP会怎么处理呢?
答案:一般情况下,服务器进程A会给TCP一个指示,让TCP维护一个适当长度的连接队列,TCP与新连接请求完成三次握手后,就会把这个连接放入连接队列中,服务器进程A会在合适的时候来从这个队列中取连接。
10、这个连接对列是否会对服务器的并发处理能力产生影响呢?如果会,会有什么影响?
答案:不会!二者没有必然关系。
11、MSS和MTU各是什么,二者是什么关系?
答案:MSS是TCP最大报文段长度,就是TCP发送数据需要对数据分段时,最大的段的字节数。MTU是最大传输单元,通常由网卡的硬件特性规定,表示通过该网卡传输的数据单元最大的字节数。MSS要受同一台机器上的MTU限制。比如MTU为1500字节,那么MSS就只能是1460字节,这是因为1460字节的数据在通过网卡向外传输时,会加上20字节的ip头和20字节的tcp头。
12、假设机器A和B的MSS分别是1400和1600,请问,A通过TCP向B发送数据时,是否可以发送长度为1600字节的数据段?
答案:不可以,虽然发送1600字节的数据段没有突破B的MSS,但是突破了A自己的MSS。这样一来,当这1600字节的数据段通过A的网卡向B发送时,会被切分为2个IP片,每个为840字节,以保证不突破A的MTU,这显然降低了传输的效率,因为两个840字节中有着相同的IP头和TCP头。
13、机器A和B有一条TCP连接,假如A想尽快断开连接,应当怎么办?
答案:A可以直接给B发送一个RST,就可以了,相当于告诉B,我关闭连接了,你看着办吧。这叫做异常关闭。
14、B的TCP收到A发来的RST,会怎么办?
答案:B的TCP会告诉上层的进程,连接已经断开了,然后就会回收这条连接的资源,并不会发送任何确认信息给A。所谓你无情休怪我不义。
15、假设A正常断开与B的TCP连接,当收到B的FIN时,A发送ACK给B,是否就算完成了4次握手,连接已经成功断开?
答案:不是,A的TCP会启动一个定时器,等待2MSL的时间,这主要是为了防止A的ACK没有成功传到B,让B以为自己的FIN没有送到A处,反复重传FIN的问题。2MSL的时间到时,如果A没有再次收到B的FIN,说明B成功收到A的ACK,A就可以安全地断开这个连接,若期间再次收到B的FIN,则A会重传ACK。