上一篇博客阐述了TCP/IP五层网络结构模型以及一些关于TCP、UDP的基础知识,这篇博客会接着写一些关于TCP拥塞控制的算法以及对TCP中常有的疑问进行解答。

TCP拥塞控制

首先了解几个概念,为下面的叙述做铺垫

  • 拥塞窗口(cwnd):TCP拥塞控制中的主要参数,表示发送端下一次最多可以发送的数据分包的个数,是来自发送端的流量控制。
  • 接收端窗口(rwnd):又称通知窗口(Advertise Window),接受端目前每次所能接收的数据分组的最大个数,是来自接收端的流量控制。
  • 慢开始门限(ssthresh):当拥塞窗口增长到慢开始门限时,启动拥塞避免算法(后面会具体阐述)。
  • 拥塞控制常用算法:慢开始、拥塞避免、快重传、快恢复。

最初,发送方不知道接收方的容纳能力,如果初次就发送较大量的数据,极有可能造成整个网络的瘫痪,TCP为了防止此类问题的出现,在通信一开始就会通过一个叫慢开始的算法得到的数值,对发送数据量进行控制。

慢开始:

由于需要考虑拥塞控制和流量控制两个方面的内容,发送端的发送窗口为min(cwnd,rwnd),但是rwnd是由对端确定的,网络环境对其没有影响,所以在考虑拥塞的时候我们一般不考虑rwnd的值,我们暂时只讨论如何确定cwnd值的大小。

在执行慢开始算法时,拥塞窗口 cwnd的初始值为 1,发送第一个报文段。当发送端收到来自接收端的ACK之后,拥塞窗口开始以1、2、4这样的指数形式增长。当拥塞窗口cwnd 增长到慢开始门限值 ssthresh 时,就改为执行拥塞避免算法,拥塞窗口按线性规律增长。

拥塞避免:

最初,拥塞窗口指数增长,可以很快进行大数据的发送,最大限度的利用网络宽带资源。当达到慢开始门限值,开始进入拥塞避免阶段,拥塞窗口开始加法增加。这样就可以避免增长过快导致网络拥塞,慢慢的增加调整到网络的最佳值。

快重传与快速恢复

上面都没有遇到网络拥塞,当真正遇到网络拥塞时,如何处理呢?当发送方连续收到三个重复的ACK之后,TCP会进入快速重传、快速恢复的阶段。

为什么叫快速重传呢?如果当发送端接收到三个重复的确认ACK时,则断定分组丢失,立即重传丢失的报文段,而不必等待重传计时器超时,相比之下,前者速度更快。

快速恢复的主要步骤:

  • 当收到3个重复ACK时,把ssthresh设置为cwnd的一半,把cwnd设置为ssthresh的值加3,然后重传丢失的报文段。
  • 再收到重复的ACK时,拥塞窗口增加1。
  • 当收到新的数据包的ACK时,把cwnd设置为第一步中的ssthresh的值。原因是因为该ACK确认了新的数据,说明从重复ACK时的数据都已收到,该恢复过程已经结束,可以回到恢复之前的状态了,也即再次进入拥塞避免状态。

TCP窗口变化

当TCP通信开始之后,网络吞吐量会逐渐上升,但是随着网络拥堵的发生,吞吐量也会急速下降。于是会再次进入吞吐量慢慢上升的过程。但是所谓TCP的吞吐量的特点就好像是在逐渐占领网络宽带的感觉。

TCP疑问解答

为什么采用三次握手而不是二次握手?

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

TCP三次握手时,第三次握手失败怎么办?

如果三次都成功的话:

  • 客户端发出了SYN包给服务器,客户端进入SYN_SEND状态。
  • 服务器收到SYN包后发出SYN+ACK数据包,服务器进入SYN_RECV状态。
  • 客户端收到SYN+ACK后发出ACK给服务器,客户端进入ESTABLISH状态
  • 服务器收到最后的ACK,服务器进入ESTABLISH状态。

我们了解一下TCP状态转换图和状态伪码可以发现:

case:SYN_RECV状态
if(收到ACK报文)
进入ESTABLISH状态
if(超时)
发送RTS报文,进入CLOSED状态
if(收到“关闭报文”)
发送FIN报文,进入FIN_WAIT_1状态
if(收到RTS报文)
进入LISTEN状态
if(收到其他报文段或报文)
发出差错报文
break

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

何为SYN洪泛攻击呢?在TCP连接建立过程中很容易碰到严重的的安全问题,称为SYN洪泛攻击。当一个或多个恶意攻击者向服务器发送大量的SYN报文时,服务器认为不同客户发来了打开请求,于是就回分配资源。然后,服务器向假冒的客户发送SYN+ACK报文,而这些报文都丢失了。如果在第三次握手这段很短的时间内,服务器大量资源被占用而没有被利用,服务器会因为资源耗尽而无法接受合法客户的连接请求。这种SYN洪泛攻击称为拒绝服务攻击的安全攻击,即攻击者用大量的请求垄断一个系统,使这个系统因超载而拒绝为合法的请求提供服务。(更多内容请参考TCP/IP协议簇一书)

关闭连接时半关闭选项的四向握手

TCP连接是全双工的,所以它允许两个方向的数据传输被独立关闭。换言之,通信的一端可以发送结束报文段给对方,告诉它本端已经完成了数据的发送,但允许继续接收来自对方的数据,直到对方也发送结束报文段以关闭连接。TCP连接的这种状态称为半关闭(half close)状态。

当客户端向服务器发送一个FIN报文段后,此连接被半关闭了。服务器发送ACK报文段来接受这个半关闭。但是服务器仍然可以发送数据,当服务器把处理完的数据都发送完毕之后,发送FIN报文段(半关闭),并且被客户发来的ACK予以确认(关闭)。

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

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

示例图解如下:

半关闭终止时间图

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

计算机网络中的TCP/UDP协议到底是怎么回事(二)的更多相关文章

  1. 计算机网络中的TCP/UDP协议到底是怎么回事(一)

    TCP/IP五层网络结构模型 物理层:物理层建立在物理通信介质的基础上,作为系统和通信介质的接口,用来实现数据链路实体间透明的比特 (bit) 流传输.只有该层为真实物理通信,其它各层为虚拟通信 数据 ...

  2. 异常处理与网络基础中的tcp,udp协议

    # 异常处理: # 什么是异常?异常和错误的区别 # Error 语法错误 比较明显的错误 在编译代码阶段就能检测出来 # Iteration 异常 在执行代码的过程中引发的异常 # 异常发生之后的效 ...

  3. TCP UDP 协议的选择

    行业应用中TCP/IP传输协议和UDP协议的选择! 中国移动.中国联通推行的GPRS网络.CDMA网络已覆盖大量的区域,通过无线网络实现数据传输成为可 能.无线Modem采用GPRS.CDMA模块通过 ...

  4. QQ--基于TCP/UDP协议的通讯原理

    QQ是一个基于TCP/UDP协议的通讯软件  发送消息的时候是UDP打洞,登陆的时候使用HTTP~因为登陆服务器其实就是一个HTTP服 务器,只不过不是常用的那些,那个服务器是腾讯自行开发的!   一 ...

  5. java 通过TCP\UDP 协议实现多人聊天,点对点,文件传送-----分服务器端和客户端

    java 通过TCP\UDP 协议实现多人聊天,点对点,文件传送-----分服务器端和客户端 启动界面如下图: 首先启动服务器: 客户端登陆,登陆成功后为: 默认发送是全部用户,是多人发送. 当在边列 ...

  6. 网络编程—网络基础概览、socket,TCP/UDP协议

    网络基础概览 socket概览 socket模块—TCP/UDP的实现 TCP/UDP总结 网络基础概览 osi七层协议各层主要的协议 # 物理层传输电信号1010101010 # 数据链路层,以太网 ...

  7. TCP/UDP协议简要梳理

    TCP/UDP协议简要梳理 TCP TCP,Transmission Control Protocol,传输控制协议是一种面向连接的.可靠的.基于字节流的传输层通信协议.在因特网协议族中,TCP所在的 ...

  8. TCP/UDP协议(二)

    面试问题:Tcp/Udp协议是什么,各有什么异同点,各自的使用场景? Tcp协议(传输控制协议) tcp是面向连接的协议,在收发数据之前,必须与对方建立可靠的连接: 三次握手:简单形象通俗描述: 主机 ...

  9. TODO:Golang语言TCP/UDP协议重用地址端口

    TODO:Golang语言TCP/UDP协议重用地址端口 这是一个简单的包来解决重用地址的问题. go net包(据我所知)不允许设置套接字选项. 这在尝试进行TCP NAT时尤其成问题,其需要在同一 ...

随机推荐

  1. centos安装lxml和pyspider

    yum -y install --nogpgcheck python34u-devel.x86_64 yum -y install libcurl-devel yum -y install libxs ...

  2. PPPOE拨号演练

    搭建PPPOE服务器,拓扑如下 PPP-Server配置如下: (config)#bba-group pppoe global (config-bba-group)#virtual-template ...

  3. C# 与 C++ 数据类型对照

    C++            C#=====================================WORD            ushortDWORD            uintUCH ...

  4. JAX-RS入门 一 :基础

    简介 JAX-RS是一套用java实现REST服务的规范,提供了一些标注将一个资源类,一个POJOJava类,封装为Web资源.标注包括: @Path,标注资源类或方法的相对路径 @GET,@PUT, ...

  5. 服务器资源共享--IIS站点/虚拟目录中访问共享目录(UNC)

    本文重点描述如何使用IIS访问共享资源来架设站点或执行 ASP.Net 等脚本. 通常情况下,拥有多台服务器的朋友在使用IIS建立站点的时候,会遇到如何把多台服务器的资源合并到一起的问题.如何让A服务 ...

  6. chart.js接口开发:X轴步长和Labels旋转角

    一. 当初为什么选择chart.js 当初项目使用库是Zepto,Zepto能支持的chart处理库太少.也是为了使得项目比较轻量化,所以选择了chart.js. 但是最后的显示结果实在太差,放弃了c ...

  7. C#高性能大容量SOCKET并发(一):IOCP完成端口例子介绍(转)

    原文地址 http://blog.csdn.net/SQLDebug_Fan/article/details/17556353 例子主要包括SocketAsyncEventArgs通讯封装.服务端实现 ...

  8. 闲话Cache:始篇

    Caching(缓存)在现代的计算机系统中是一项最古老最基本的技术.它存在于计算机各种硬件和软件系统中,比如各种CPU, 存储系统(IBM ESS, EMC Symmetrix…),数据库,Web服务 ...

  9. SCVMM配置

    SCVMM添加工作组主机 1.准备一台物理主机并且安装WindowsServer 2012名为HV2(工作组不加域)接着添加hyper-v角色 2.把SCVMM1服务器上的SCVMM2012代理程序( ...

  10. Codeforces Round #221 (Div. 1) B. Maximum Submatrix 2 dp排序

    B. Maximum Submatrix 2 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/problemset ...