一、TCP的三次握手与四次挥手
1、三次握手
定义:指建立一个TCP连接时,需要客户端和服务器总共发送3个包。建立连接的过程为三次握手
目的:连接服务器指定端口,建立TCP连接,并同步连接双方的序列号和确认号并交换TCP窗口大小信息。
可能触发三次握手的情况:在socket编程中,客户端执行connect()时,将触发三次握手。
三次握手的作用:
①使得通讯双方都做好通讯准备;
②告诉对端本端通讯所选用的报文标识号;
③防止已失效的连接请求报文段又突然传递到了服务器,从而产生错误。
三次握手的过程:
序列号seq:占4个字节,用来标记数据段的顺序,TCP把连接中发送的所有数据字节都编上一个序号,第一个字节的编号由本地随机产生;给字节编上序号后,就给每一个报文段指派一个序号;序列号seq就是这个报文段中的第一个字节的数据编号。
确认号ack:占4个字节,期待收到对方下一个报文段的第一个数据字节的序号;序列号表示报文段携带数据的第一个字节的编号;而确认号指的是期望接收到下一个字节的编号;因此当前报文段最后一个字节的编号+1即为确认号。
确认ACK:占1位,仅当ACK=1时,确认号字段才有效。ACK=0时,确认号无效
同步SYN:连接建立时用于同步序号。当SYN=1,ACK=0时表示:这是一个连接请求报文段。若同意连接,则在响应报文段中使得SYN=1,ACK=1。因此,SYN=1表示这是一个连接请求,或连接接受报文。SYN这个标志位只有在TCP建产连接时才会被置1,握手完成后SYN标志位被置0。
终止FIN:用来释放一个连接。FIN=1表示:此报文段的发送方的数据已经发送完毕,并要求释放运输连接
2、四次挥手
关闭连接的过程为四次挥手,由于TCP的全双工的通讯,所以每个方向都必须单独进行关闭。
四次挥手的过程:
当一方完成他的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能继续发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。
问题:
1、三次握手,每一次都携带什么数据?为什么要给确认报文段中的ACK的值+1?
seq是数据包本身的序列号;ack是期望对方继续发送的那个数据包的序列号。
2、为什么是三次握手?两次可以么?四次呢?
显然是不可以的。
① 客户端发送SYN包A1,由于网络链路问题,到达时间滞后,因为客户端迟迟收不到服务器的响应,以为丢包,清理A1,重发SYN包B1,B1顺利到达,响应B2,与客户端建立连接,A1姗姗来迟,响应A2,由于A1被清理,客户端不理会A2,但是服务器还是会维持这个僵尸连接。
② 避免SYN攻击。
两次握手是不可以的,可能会发生死锁。服务器崩溃。
四次握手可以,但是没有必要,浪费资源。
3、三次握手哪个阶段容易出现攻击?哪个阶段会出现异常?
SYN溢出攻击。出现在第二阶段,如果客户端伪造大量的SYN同步报文,服务端就会依次消耗掉很多资源来保存客户端信息,并进行确认,实际确认是会失败的,但失败需要一定的时间,因为服务器会连续多次进行第二次握手确认后才认定失败。短时间内会有大量的SYN同步报文涌向服务端,服务器资源可能被耗尽,就可能导致正常的客户端得不到响应而失败。
第二阶段可能出现异常,如果服务器相应的端口未打开,会回复RST复位报文,握手失败。此外,listen创建的监听队列达到上限,也可能失败。
4、为什么是四次挥手?三次可以么?可以的话,在什么情况可以三次能完成?
因为TCP连接是全双工的也就是说接收到FIN只是说没有数据再发过来但是还是可以发送数据的,也就是接受到一个FIN只是关闭了一个方向的数据传输,另一个方向还可以继续发送数据。在四次挥手的时候也是这样前两次挥手只是确认关闭了一个方向的数据,加上后面两次挥手才真正的关闭了整个全双工连接。
三次是可以的,当本端关闭了连接,恰好也同时收到了对方的FIN报文,此时可以把自己的FIN和给对端的确认ACK合在一起发送,就变成了三次。
5、TIME_WAIT 状态存在的意义
状态:主动断开连接的一端收到对端的FIN报文段并且将ACK报文段发出后的一种状态。先关闭的一段的另一端会出现time_wait状态
意义:1)保证迟来的数据能被识别并释放;
2)保证可靠的终止TCP连接。保证对端能收到最后一个ACK,如果ACK丢失,在TIME_WAIT状态本端还可以接收到 对端重传的FIN报文段并重新发送ACK。所以在TIME_WAIT 的存在时间为2MSL。MSL(报文段最大生存时间)
为什么需要time_wait状态?
1)保证客户端发送的最后一个ACK报文能够到达服务器;
2)防止已失效的报文段。(客户端在发送最后一个ACK之后,再经过2MSL就可以使本连接持续时间内所产生的所有报文段都从网络中消失)
6、TIME_WAIT和CLOSE_WAIT状态有什么区别?
CLOSE_WAIT是被动关闭的一端在接收到对端关闭请求(FIN报文段)并且将ACK发送出去后所处的状态,这种状态表示:收到了对端关闭请求,但是本端还没有完成工作,还未关闭。
TIME_WAIT状态是主动关闭的一端在本端已经关闭的前期下,收到对端的关闭请求并且将ACK发送出去后所处的状态。这种状态表示:双方都已经完成工作,只是为了确保迟来的数据报能被识别并丢弃,可靠的终止TCP连接。
7、TCP和UDP用一个端口发送信息是否冲突?
不冲突。TCP和UDP可以绑定同一个端口进行通信。因为数据接收时根据五元组(传输协议、源IP、目的IP、源端口、目的端口)判断接受者的。