TCP笔记

来源:互联网 发布:画原型的软件 编辑:程序博客网 时间:2024/05/01 10:39

转载自:http://blog.csdn.net/kobejayandy/article/details/38933499
    http://blog.csdn.net/kobejayandy/article/details/38933513
    http://blog.csdn.net/kobejayandy/article/details/18183077
    http://blog.csdn.net/kobejayandy/article/details/46641791
    http://blog.csdn.net/xifeijian/article/details/44260995

TCP三次握手

  所谓三次握手(Three-way Handshake),是指建立一个TCP连接时,需要客户端和服务器总共发送3个包。
  第一次握手: 客户端发送一个TCP的SYN标志位置1的包指明客户打算连接的服务器的端口,以及初始序号X,保存在包头的序列号(Sequence Number)字段里。
  第二次握手: 服务器发回确认包(ACK)应答。即SYN标志位和ACK标志位均为1同时,将确认序号(Acknowledgement Number)设置为客户的ISN加1以.即X+1。
  第三次握手: 客户端再次发送确认包(ACK)SYN标志位为0,ACK标志位为1.并且把服务器发来ACK的序号字段+1,放在确定字段中发送给对方.并且在数据段放写ISN的+1

SYN攻击

  在三次握手过程中,服务器发送SYN-ACK之后,收到客户端的ACK之前的TCP连接称为半连接(half-open connect).此时服务器处于SYN_RECV状态.当收到ACK后,服务器转入ESTABLISHED状态。
  如果server端接到了client发的SYN后返回了SYN-ACK,之后client掉线了,server端没有收到client回来的ACK,那么,这个连接处于一个中间状态,即没成功,也没失败。于是,server端如果在一定时间内没有收到的ACK会重发SYN-ACK。在Linux下,默认重试次数为5次,重试的间隔时间从1s开始,5次的重试时间间隔为1s, 2s, 4s, 8s, 16s,总共31s,第5次发出后还要等32s才知道第5次也超时了,所以,总共需要 1s + 2s + 4s+ 8s+ 16s + 32s = 2^6 -1 = 63s,TCP才会把断开这个连接。
  SYN Flood攻击就是攻击客户端在短时间内伪造大量不存在的IP地址,向服务器不断地发送SYN包,服务器回复确认包,并等待客户的确认,由于源地址是不存在的,服务器需要不断的重发直至超时,这些伪造的SYN包将长时间占用未连接队列,正常的SYN请求被丢弃,目标系统运行缓慢,严重者引起网络堵塞甚至系统瘫痪。
  SYN攻击是一个典型的DDOS攻击。检测SYN攻击非常的方便,当服务器上出现大量的半连接状态时,特别是源IP地址是随机的,基本上可以断定这是一次SYN攻击.在Linux下可以如下命令检测是否被SYN攻击: netstat -n -p TCP | grep SYN_RECV。
  在linux中使用SYN cookie或SYN COOKIE 防火墙来应对SYN Flood攻击。

TCP 四次挥手

  TCP的连接的断开需要发送四个包,因此称为四次挥手(four-way handshake)。客户端或服务器均可主动发起挥手动作。
  TCP连接是全双工的,因此每个方向都必须单独进行关闭。这原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。
  TCP客户端发送一个FIN,用来关闭客户到服务器的数据传送;服务器收到这个FIN,它发回一个ACK,确认序号为收到的序号加1,和SYN一样,一个FIN将占用一个序号; 服务器关闭客户端的连接,发送一个FIN给客户端;客户段发回ACK报文确认,并将确认序号设置为收到序号加1。

滑动窗口

  TCP通过滑动窗口的概念来进行流量控制。设想在发送端发送数据的速度很快而接收端接收速度却很慢的情况下,为了保证数据不丢失,显然需要进行流量控制,协调好通信双方的工作节奏。
  所谓滑动窗口,可以理解成接收端所能提供的缓冲区大小。TCP利用一个滑动的窗口来告诉发送端对它所发送的数据能提供多大的缓冲区。由于TCP数据报中窗口标志由16位bit所定义,所以接收端TCP能最大提供65535个字节的缓冲。由此,可以利用窗口大小和第一个数据的序列号计算出最大可接收的数据序列号。
  滑动窗口本质上是描述接受方的TCP数据报缓冲区大小的数据,发送方根据这个数据来计算自己最多能发送多长的数据。如果发送方收到接受方的窗口大小为0的TCP数据报,那么发送方将停止发送数据,等到接受方发送窗口大小不为0的数据报的到来。
  窗口合拢(左移):在收到对端数据后,自己确认了数据的正确性,这些数据会被存储到缓冲区,等待应用程序获取。但这时候因为已经确认了数据的正确性,需要向对方发送确认响应ACK,又因为这些数据还没有被应用进程取走,这时候便需要进行窗口合拢,缓冲区的窗口左边缘向右滑动。这种现象发生在数据被发送和确认的时候。
  窗口张开(右移):窗口收缩后,应用进程一旦从缓冲区中取出数据,TCP的滑动窗口需要进行扩张,这时候窗口的右边缘向右扩张,实际上窗口这是一个环形缓冲区,窗口的右边缘扩张会使用原来被应用进程取走内容的缓冲区。在窗口进行扩张后,需要使用ACK通知对端,这时候ACK的序号依然是上次确认收到包的序号。这种现象发生在接受端处理了数据以后。
  窗口收缩:窗口的右边缘向左滑动,称为窗口收缩,这种现象不常发生。
  TCP就是用这个窗口,慢慢的从数据的左边移动到右边,把处于窗口范围内的数据发送出去(但不用发送所有,只是处于窗口内的数据可以发送。)。这就是窗口的意义。窗口的大小是可以通过socket来制定的,4096并不是最理想的窗口大小,而16384则可以使吞吐量大大的增加。

慢启动(拥塞窗口)

  数据在传输的时候不能只使用一个窗口协议,还需要有一个拥塞窗口来控制数据的流量,使得数据不会一下子都跑到网路中引起“拥塞”。拥塞窗口最初使用指数增长的速度来增加自身的窗口,直到发生超时重传,再进行一次微调。
  拥塞窗口(cwnd)原理:
  1.发送方开始发送一个报文,然后等待ACK,当收到该ACK时,拥塞窗口从1增加到2,即可以发送2个报文段,然后等待ACK,当收到这两个报文段的ACK时,拥塞窗口就增加为4。这是一种指数增加的关系。该过程即慢启动。
  2.当拥塞窗口达到慢启动门限后,拥塞窗口不再以指数增长,而是线性增长,直到拥塞发生(超时或收到重复确认)。该过程即拥塞避免阶段。
  3.当发生拥塞时,慢启动门限会重新设置为当前窗口的一半,拥塞窗口被设置为1,当新的数据被确认后,在指数增加拥塞窗口,重复上述过程。
  在TCP Reno版本中增加了快速重传和快速恢复算法。
  快速重传:当发送方收到三个重复的ack后,不会进入慢启动状态,而是立刻重传丢失的报文。因为只有接收方收到新的报文段的时候,才会发送重复的ack,这表明TCP连接上仍然有数据流动,所以应该避免使用慢启动降速。
  快速恢复算法:快速重传之后,接下来执行的不是慢启动而是拥塞避免算法。
  慢启动算法用于保证新分组进入网络的速率与另一端返回确定的速率相等。拥塞窗口是发送使用的流量控制,通告窗口是接收方使用的流量控制。
  总的来说,慢启动、拥塞避免、快速重传和快速恢复是TCP拥塞控制的算法。

定时器

延时定时器
  TCP中对数据的确认往往是延迟的,一般情况是两个TCP数据对应一个确认,在时延定时器没有溢出的情况下。如果时延定时器溢出了,那么自然也会发送确认报文。当TCP收到报文时候,启动延时定时器,比如200ms。

重传定时器
  目的是为了获得对端的确认报文。如果多次重传仍然没有获得确认,则会发送复位报文RST。

坚持定时器
  由于TCP没有对ACK的确认机制,所以当接收端窗口从0恢复到一定值的时候,如果接收端发给发送端的ACK报文(标识窗口大小)丢失了,发送端就永远不知道接收端的窗口恢复情况了。所以发送端会定时发送带一个字节的ACK给接收端,查看接收端的确认报文中的窗口信息。

保活定时器
  由于物理原因,处于空闲状态的TCP连接一端崩溃的时候,TCP有保活机制来判断对端是否仍然工作。保活定时器默认是关闭的。

0 0
原创粉丝点击