腾讯面试TCP连接相关问题

这一片博客作为积累腾讯面试问题的博客,以后还会有补充的。

Q1:TCP报文长度是在TCP三次握手中那一次确定的?

这个是关于TCP报文的最大报文段长度mss的相关问题。在TCP连接的前两次握手中(SYN报文中),通信双方都会在选项字段中告知对方自己期待收到最大报文长度(mss值),以双方两个SYN报文中最小的mss最为本次数据传输的mss值。通信双方以“协商”的方式来确定报文长度的,前两次握手是告诉对方自己的mss值,在第三次握手确定mss值

Q2:TCP报文长度是由什么确定的?

这个跟具体传输网络有关,以太网的MTU为1500字节,Internet的MTU为576字节。

MTU是网络层的传输单元,那么MSS = MTU - 20字节(IP首部) - 20字节(TCP首部)。所以以太网的MSS为1460字节,而Internet的MSS为536字节。

Q3:TCP三次握手中,accept函数是发生在TCP三次握手的那个阶段?

服务器端的listen函数:int listen(int sockfd, int backlog);其中sockfd是与某个服务绑定的套接口,backlog是允许阻塞的最大请求个数。

在服务器端存在着两个队列,一个是已经通过三次握手“建立连接的队列“(FIFO with established state)处于Established状态,另一个是“未完成连接的队列”( FIFO with syn_rcvd state)处于SYN_RCVD状态。这两个队列的长度之和就是backlog。在服务器端的accept函数,相当于从“建立连接的队列”中取出一个来进行后续的数据交换。

而三次握手是发生在connect函数中,connect函数执行成功就相当于已经建立三次握手。

Q4:如果TCP连接过程中,第三次握手失败怎么办?

server给client返回一个SYN+ACK报文后server进入SYN_RCV状态。client收到SYN+ACK报文后进入ESTABLISHED状态,并且给server返回一个ACK报文。

server端发送了SYN+ACK报文后就会启动一个定时器,等待client返回的ACK报文。如果第三次握手失败的话client给server返回的ACK报文,在传输过程中出现故障,server并不能收到这个ACK报文。那么server端就会启动超时重传机制,超过规定时间后重新发送SYN+ACK,重传次数根据/proc/sys/net/ipv4/tcp_synack_retries来指定,默认是5次。如果重传指定次数到了后,仍然未收到ACK应答,那么一段时间后,server自动关闭这个连接。但是client认为这个连接已经建立,如果client端向server写数据,server端将以RST包响应,方能感知到server的错误。

理解了下面的状态转换图,

腾讯面试TCP连接相关问题_第1张图片

每一个状态的转换伪代码整理下:

腾讯面试TCP连接相关问题_第2张图片

腾讯面试TCP连接相关问题_第3张图片

腾讯面试TCP连接相关问题_第4张图片

腾讯面试TCP连接相关问题_第5张图片

腾讯面试TCP连接相关问题_第6张图片

腾讯面试TCP连接相关问题_第7张图片

第58行指明了当第三次握手失败时的处理操作,可以看出当失败时服务器并不会重传ack报文,而是直接发送RTS报文段,进入CLOSED状态。这样做的目的是为了防止SYN洪泛攻击。

“如何保证TCP连接的可靠性?”

这个问题我在《TCP/IP协议》这本书里边有的,并且我面试前几天还看过,不过这回让我说我感觉肯定没有当初答的好了。在这里我再次总结下:

TCP通过以下方式提供数据传输的可靠性:

(1)TCP在传输数据之前,都会把要传输的数据分割成TCP认为最合适的报文段大小。在TCP三次我握手的前两次握手中(也就是两个SYN报文段中),通过一个“协商”的方式来告知对方自己期待收到的最大报文段长度(MSS),结果使用通信双发较小的MSS最为最终的MSS。在SYN=1的报文段中,会在报文段的选项部分来指定MSS大小(相当于告知对方自己所能接收的最大报文段长度)。在后续通信双发发送应用层数据之前,如果发送数据超过MSS,会对数据进行分段。

(2)使用了超时重传机制。当发送一个TCP报文段后,发送发就会针对该发送的段启动一个定时器。如果在定时器规定时间内没有收到对该报文段的确认,发送方就认为发送的报文段丢失了要重新发送。

(3)确认机制。当通信双发的某一端收到另一个端发来的一个报文段时,就会返回对该报文段的确认报文。

(4)首部校验和。在TCP报文段首部中有16位的校验和字段,该字段用于校验整个TCP报文段(包括首部和数据部分)。IP数据报的首部校验和只对IP首部进行校验。TCP详细的校验过程如下,发送TCP报文段前求一个值放在校验位,接收端接受到数据后再求一个值,如果两次求值形同则说明传输过程中没有出错;如果两次求值不同,说明传输过程中发生错误,无条件丢弃该报文段引发超时重传。

(5)使用滑动窗口流量控制协议。

(6)由于在TCP发送端可能对数据分段,那么在接收端会对接收到的数据重新排序。


你可能感兴趣的:(腾讯面试TCP连接相关问题)