TCP相关

TCP相关

标签(空格分隔): 面试


预备

特点

TCP的特点:

  1. TCP是面向连接的传输协议
  2. 每条TCP连接只能有两个端点,每条TCP连接只能是点对点(一对一)
  3. TCP提供可靠的交付服务,保证传送的数据无差错,不丢失,不重复且有序
  4. TCP提供全双工通信,允许双方的应用进程在任何时候都能发送数据
  5. TCP是面向字节流的,将数据看成 一连串的无结构的字节流

报文段

TCP报文段:

  1. 16位的源端口字段包含初始化通信的端口号。
  2. 16位的目的端口字段定义传输的目的。
  3. 序列号字段(seq字段):表示在这个报文段中所发送的数据的第一个字节的序号。
  4. 确认号字段(ack字段):32位的确认号字段标识期望收到的下一个段的第一个字节,并声明此前的所有数据已经正确无误地收到

控制字段标志

  1. 紧急位URG:当URG=1时,表示TCP包的紧急指针字段有效,用来保证TCP连接不被中断,并且督促中间齐备尽快处理这些紧急数据(优先级高)。

  2. 确认位ACK:只有ACK=1时确认字段有效,也即TCP应答号将包含在TCP段中,为0则确认号无效。TCP规定,在连接建立后所有传送的报文段都必须把ACK置为1。

  3. 推送位PSH:这个标志表示Push操作。接收TCP收到PSH=1的报文段后,立即送给应用程序,而不是在缓冲区中等到整个缓存都填满了再向上交付。

  4. 复位位RST:当RST=1时表明TCP连接中出现严重的差错,必须释放连接,然后再重新建立运输连接。

  5. 同步位SYN:同步SYN=1表示这是一个连接请求或连接接收报文。当SYN=1,ACL=0时,表明这是一个连接请求报文,对方若统一建立连接,则在响应报文中使用SYN=1,ACK=1。即SYN=1就表示这是一个连接请求或连接接收报文。

  6. 终止位FIN:FIN=1,表示发送端已经发送到数据末尾,数据传送完成,发送FIN标志位的TCP段,连接将被断开。

三次握手

三次握手过程

第一步:

客户机服务器发送一个连接请求报文段SYN=1,并随机选择一个起始序号seq=x,然后客户端进入SYN_SEND状态,等待服务器确认。

第二步:

服务器收到连接请求报文后,向客户机发回确认(SYN=1,ACK=1),并分配TCP缓存的变量服务器进入SYN_RCVD状态。

第三步:

当客户机收到服务器的返回的确认报文段(SYN+ACK包)后,还要向服务器给出确认包(ACK(ack=y+1)),并且也要给该连接分配缓存和变量。这个报文段的ACK被置为1,序号为 x+1,确认字段号为ack=y+1。之后客户端和服务器进入ESTABLISHED状态,完成三次握手。

为什么需要三次握手

TCP是可靠的传输控制协议,三次握手能保证数据可靠传输又能提高传输效率

如果TCP的握手是两次:

  1. 如果客户端发给服务器的连接请求报文网络延迟了。客户端没收到服务端的返回确认,就会重发。如果此后,延迟的连接请求报文发送到了服务端,就又建立了连接。

  2. 如果服务端给客户端发送的确认连接报文因为网络原因,报文被丢弃。此时服务端认为已经建立好连接,但是客户端没有收到确认报文,认为没有建立好连接。client会重发SYN报文,此时server已经处于就绪状态,认为已经建立好连接。

如果TCP的握手是四次:

  1. client给server发送SYN同步报文;
  2. server收到SYN后,给client回复ACK确认报文;
  3. server给client发送SYN同步报文;
  4. client给server发送ACK确认报文。

第2.3步之间,server和client没有任何的数据交互,分开发送相当于多发了一次TCP报文段,SYN和ACK标识只是TCP报头的一个标识位。很明显,这两步可以合并,从而提高连接的速度和效率。

四次挥手

四次挥手过程

参与TCP连接的两个进程中的任何一个都能终止该连接。

假设客户机主动关闭连接:

第一步:

客户端向服务端发送一个连接释放报文段FIN=1,意思是“我不会再给你发数据了”,此时客户端进入FIN_WAIT_1状态

第二步:

服务器接收到连接释放报文字段后即发出确认ACK进入CLOSE_WAIT状态等待结束

此时客户机到服务器这个方向的连接就释放了,进入FIN_WAIT_2状态,TCP处于半关闭状态。

但服务器若要发送数据,客户机仍要接受,即从服务器到客户机这个方向的连接尚未关闭。

这一步相当于:服务器说“好,我知道你不会给我发数据了,但是我还可以给你发”

第三步:

服务器给若也要关闭,就给客户机发送FIN=1的连接释放报文段。并进入LAST_ACK 最后确认状态。即服务器告诉客户机:我的数据也发送完了,不会再给你发数据了。

第四步:

客户机收到连接释放报文后,必须发出确认,ACK字段被置为1。服务端接收到之后进入

但此时TCP连接还没有释放掉,客户机进入TIME_WAIT状态必须等待时间2MSL后,客户机才进入到连接关闭状态。

相当于客户机告诉服务器:OVER(不用回了)。然后客户机再等待2MSL后关闭。

为什么需要四次挥手

TCP是全双工的连接,必须两端同时关闭连接,连接才算真正关闭。

如果一方已经准备关闭写,但是它还可以读另一方发送的数据。发送给FIN结束报文给对方对方收到后,回复ACK报文。当这方也已经写完了准备关闭,发送FIN报文,对方回复ACK。两端都关闭,TCP连接正常关闭。

为什么要有TIME_WAIT状态,为什么要等待2MSL

主动发起关闭连接的操作的一方将达到TIME_WAIT状态,而且这个状态要保持Maximum Segment Lifetime的两倍时间。

原因是:

  • 保证TCP协议的全双工连接能够可靠关闭
  • 保证这次连接的重复数据段从网络中消失

    1. 可靠终止TCP连接。如果最后一个ACK报文因为网络原因被丢弃,此时服务端因为没有收到ACK而超时重传FIN报文,处于TIME_WAIT状态的客户端可以继续对FIN报文做回复,向server发送ACK报文。

    2. 保证让迟来的TCP报文段有足够的时间被识别和丢弃。连接结束了,网络中的延迟报文也应该被丢弃掉,以免影响立刻建立的新连接。

msl、ttl及rtt的区别

MSL为“报文最大生存时间”,他是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。RFC793中规定MSL为2分钟,实际应用中常用的是30秒,1分钟和2分钟等。

ip头中有一个TTL域,为“生存时间”,是一个ip数据报可以经过的最大路由数,每经过一个处理他的路由器此值就减1,当此值为0则数据报将被丢弃,同时发送ICMP报文通知源主机。

RTT是客户到服务器往返所花时间,TCP含有动态估算RTT的算法。TCP还持续估算一个给定连接的RTT,这是因为RTT受网络传输拥塞程序的变化而变化

如何保证TCP连接的可靠性

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

  1. TCP在传输数据之前,都会把要传输的数据分割成TCP认为最合适的报文段大小MSS。如果发送数据超过MSS,会对数据进行分段。

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

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

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

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

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

其他问题

为什么建立连接需要三次握手,而断开连接需要四次握手

因为每个方向都需要一个FIN和ACK,当一端发送了FIN包之后,处于半关闭状态,此时仍然可以接收数据包。

在建立连接时,服务器可以把SYN和ACK放在一个包中发送。

但是在断开连接时,如果一端收到FIN包,但此时仍有数据未发送完,此时就需要先向对端回复FIN包的ACK。等到将剩下的数据都发送完之后,再向对端发送FIN,断开这个方向的连接。

因此很多时候FIN和ACK需要在两个数据包中发送,因此需要四次挥手

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

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

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

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

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

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

Socket accept() 侦听要连接到此套接字并接受它。

在服务器端存在着两个队列,一个是已经通过三次握手“建立连接的队列“处于Established状态,另一个是“未完成连接的队列”处于SYN_RCVD状态。在服务器端的accept函数,相当于从“建立连接的队列”中取出一个来进行后续的数据交换。发生在

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

如果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的错误。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值