TCP之为什么系列

1、为什么需要三次握手

这里写图片描述

LISTEN : 接受连接状态 
ESTABLISHED : 连接建立

简洁得讲,为了保证服务端能收接受到客户端的信息并能做出正确的应答而进行前两次(第一次和第二次)握手,为了保证客户端能够接收到服务端的信息并能做出正确的应答而进行后两次(第二次和第三次)握手

那么如果不三次握手会有什么后果呢?

谢希仁版《计算机网络》中的例子是这样的,“已失效的连接请求报文段”的产生在这样一种情况下:client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的运输连接已经建立,client没有响应,server会一直重新发送SYN+ACK(有最大重传次数),这样,server的很多资源就白白浪费掉了。采用“三次握手”的办法可以防止上述现象发生。例如刚才那种情况,client不会向server的确认发出确认。server由于收不到确认,就知道client并没有要求建立连接。。

主要目的为了防止失效的连接请求报文段突然又传送到主机 ,造成连接建立而server端一直等待,浪费资源。

2、为什么要四次挥手

这里写图片描述

  • FIN-WAIT-1:表示等待对方的FIN报文
  • FIN-WAIT-2:也是表示等待对方的FIN报文,此时是进入到了半关闭状态
  • TIME-WAIT:表示收到了对方的FIN报文,并发送出了ACK报文,就等2MSL后即可回到CLOSED可用状态了,如果FIN_WAIT_1状态下,收到了对方同时带 FIN标志和ACK标志的报文时,可以直接进入到TIME_WAIT状态,而无须经过FIN_WAIT_2状态。
  • CLOSE_WAIT: 已收到对方的FIN,自己也回复了ACK,对方处于关闭状态,此时全局处于半关闭状态,等待自己这端关闭连接
  • LAST_ACK: 等待最后一个ACK
  • CLOSE:表示已关闭连接

这是因为TCP是全双工的,并且是半关闭的。 
主机A发送FIN到主机B,只是意味着主机A到主机B的连接释放了,而主机B还可以发送数据到主机A;只有主机B发送FIN到A,并且A回应了ACK,才是完整得释放了连接

3、Dos攻击和SYN洪水攻击

TCP三次握手的一些重要概念:

  • 半连接:收到SYN包而还未收到ACK包时的连接状态称为半连接,即尚未完全完成三次握手的TCP连接。
  • 半连接队列:在三次握手协议中,服务器维护一个半连接队列,该队列为每个客户端的SYN包(SYN=i )开设一个条目,该条目表明服务器已收到SYN包,并向客户发出确认,正在等待客户的确认包。这些条目所标识的连接在服务器处于SYN_ RECV状态,当服务器收到客户的确认包时,删除该条目,服务器进入ESTABLISHED状态。
  • Backlog参数:表示半连接队列的最大容纳数目。
  • SYN-ACK重传次数:服务器发送完SYN-ACK包,如果未收到客户确认包,服务器进行首次重传,等待一段时间仍未收到客户确认包,进行第二次重传,如果重传次数超过系统规定的最大重传次数,系统将该连接信息、从半连接队列中删除。注意,每次重传等待的时间不一定相同。
  • 半连接存活时间:是指半连接队列的条目存活的最长时间,也即服务从收到SYN包到确认这个报文无效的最长时间,该时间值是所有重传请求包的最长等待时间总和。有时也称半连接存活时间为Timeout时间、SYN_RECV存活时间。

Dos攻击的表现形式: 
1,制造大流量无用数据,造成通往被攻击主机的网络拥塞,使被攻击主机无法正常和外界通信。 
2,利用被攻击主机提供服务或传输协议上处理重复连接的缺陷,反复高频的发出攻击性的重复服务请求,使被攻击主机无法及时处理其它正常的请求。 
3,利用被攻击主机所提供服务程序或传输协议的本身实现缺陷,反复发送畸形的攻击数据引发系统错误的分配大量系统资源,使主机处于挂起状态甚至死机。

Syn洪水攻击 
SYN洪水攻击属于DoS攻击的一种,它利用TCP协议缺陷,通过发送大量的半连接请求,耗费CPU和内存资源。SYN攻击除了能影响主机外,还可以危害路由器、防火墙等网络系统,事实上SYN攻击并不管目标是什么系统,只要这些系统打开TCP服务就可以实施。服务器接收到连接请求(SYN=i )将此信息加入未连接队列,并发送请求包给客户端( SYN=j,ACK=i+1 ),此时进入SYN_RECV状态。当服务器未收到客户端的确认包时,重发请求包,一直到超时,才将此条目从未连接队列删除。配合IP欺骗,SYN攻击能达到很好的效果,通常,客户端在短时间内伪造大量不存在的IP地址,向服务器不断地发送SYN包,服务器回复确认包,并等待客户的确认,由于源地址是不存在的,服务器需要不断的重发直至超时,这些伪造的SYN包将长时间占用未连接队列,正常的SYN 请求被丢弃,目标系统运行缓慢,严重者引起网络堵塞甚至系统瘫痪。过程如下:

  攻击主机C(地址伪装后为C’)—–大量SYN包—->被攻击主机

  C’<——-SYN/ACK包—-被攻击主机

  由于C’地址不可达,被攻击主机等待SYN包超时。攻击主机通过发大量SYN包填满未连接队列,导致正常SYN包被拒绝服务。另外,SYN洪水攻击还可以通过发大量ACK包进行DoS攻击。

http://blog.csdn.net/justdoitflyer/article/details/12870907

SYN攻击防范 
第一种是缩短SYN Timeout时间 
第二种方法是设置SYN Cookie,就是给每一个请求连接的IP地址分配一个Cookie,如果短时间内连续受到某个IP的重复SYN报文,就认定是受到了攻击,以后从这个IP地址来的包会被一概丢弃。

第三次握手失败 
说法1: 
TCP为了防止SYN攻击,当第三次握手失败,主机并不会重传ack报文,而是直接发送RTS报文段,进入CLOSED状态。这样做的目的是为了防止SYN洪泛攻击。

说法2: 
当客户端收到服务端的SYN+ACK应答后,其状态变为ESTABLISHED,并会发送ACK包给服务端,准备发送数据了。如果此时ACK在网络中丢失,过了超时计时器后,那么Server端会重新发送SYN+ACK包,重传次数根据/proc/sys/net/ipv4/tcp_synack_retries来指定,默认是5次。如果重传指定次数到了后,仍然未收到ACK应答,那么一段时间后,Server自动关闭这个连接。但是Client认为这个连接已经建立,如果Client端向Server写数据,Server端将以RST包响应,方能感知到Server的错误。

4、当关闭连接时最后一个ACK丢失怎么办

如果最后一个ACK丢失的话,TCP就会认为它的FIN丢失,进行重发FIN。在客户端收到FIN后,就会设置一个2MSL计时器,2MSL计时器可以使客户等待足够长的时间,使得在ACK丢失的情况下,可以等到下一个FIN的到来。如果在TIME-WAIT状态汇总有一个新的FIN到达了,客户就会发送一个新的ACK,并重新设置2MSL计时器。 
这里写图片描述

如果重传FIN到达客户端时,客户端已经进入CLOSED状态时,那么客户就永远收不到这个重传的FIN报文段,服务器收不到ACK,服务器无法关闭连接。

但是服务器并不会一直无法关闭,服务器会进行不断的探查,会发送十个间隔为75秒的探查,如果探查都没有收到回应,则认为客户端已经关闭,服务器也将关闭,终止链接。 
http://www.jianshu.com/p/eab86c0d1612

5、为什么TIME_WAIT状态需要经过2MSL才能返回到CLOSE状态?

MSL : TCP中最大报文段生存时间,即报文段被丢弃前在网络中的最长时间 
每一个报文段的最大生存时间是1MSL

  • 为了保证发送的最后一个ACK报文段能够到达B 
    当发送端发送最后一个ACK报文段给B,每一个报文段的最大生存时间是1MSL,如果这个ACK丢失了,而A却在2MSL后才关闭,那么A还有时间重发ACK给B,这样就确保了A的最后一个ACK能够到达B
  • 防止“已失效的连接请求报文段”出现在本连接中。 
    在发送完最后一个ACK报文段后,再经过实践2MSL,就可以使本连接持续的时间内所产生的所有报文段,都从网络中消失。这样就可以使下一个新的连接中不会出现这种就得连接请求报文段。

6、TCP如何保证可靠性?

  1. TCP会根据MSS进行分段,这样避免了在网络层中ip分组进一步分片
  2. 定时器和重传策略:当TCP发出一个段之后,启动定时器,等待目的端确认收到这个报文段。如果发送端不能及时收到确认,将重发这个报文段
  3. 当TCP收到TCP连接另一端的数据,它将发送一个ack,这个ack不是立即发送,通常延迟几分之一秒,为什么?
  4. TCP会保证头部和数据的校检和,这个校检和用来检测数据在端到端的传输中是否发生差错,如果有差错,TCP接收端将丢弃这个报文段,希望发送端重发
  5. 接收端中IP数据报的到达可能会失序,所以TCP报文段也可能会失序,所以TCP可能会进行重排序,再交给应用层
  6. TCP接收端对重复的数据会丢弃
  7. 流量控制:收发双方各有一个缓冲空间和一个窗口

7、连接建立会有两次超时,且第一次超时大概是6s,而第二次超时却准确是24s,这是为什么?

未知

8、为什么要有半关闭状态?

未知

9、半打开状态

如果一方已经关闭或异常终止,没有发送FIN给另一方,那么另一方就不知道,仍然处于连接状态,我们将这样的TCP连接称为半打开状态。只要不打算在半打开状态上传输数据,处于连接状态的一方就不会检测出这种状态

产生原因:

  • 一方突然关机

半关闭和半打开的区别

半关闭状态,一端已发送FIN,等待另一方的FIN;半打开状态,一方都不知道另一方已经崩溃了

10、同时打开

同时打开:两个应用程序同时执行主动打开

需要条件:

  • 每一方必须发送SYN,并且每一方必须接收到对方发来的SYN
  • 每一方都必须使用一个对方熟知的本地端口

实例: 
主机A的一个应用程序使用本地端口7777,并发送SYN给主机B的端口8888,执行主动打开; 
主机B的一个应用程序使用本地端口8888,并发送SYN给主机A的端口7777,执行主动打开;

反例: 
主机A的Telnet客户端与主机B中的Telnet服务端建立连接; 
主机B的Telnet客户端与主机A中的Telnet服务端建立连接;

  • Telnet是被动打开
  • Telnet选择的本地端口不是另一端熟悉的端口

同时打开双方的状态

四次握手

这里写图片描述

11、同时关闭

这里写图片描述

猜你喜欢

转载自blog.csdn.net/fanleiym/article/details/81660911