TCP知识点总结

  要说计算机网络的重点肯定是TCP/IP协议族了,这两个协议几乎涵盖了整个网络通信的流程。弄清楚客户端和服务器端之间的通信过程,基本上就对TCP/IP掌握的差不多了。所以接下来要开始介绍这篇文章的主角TCP协议了。

   先简单介绍一下TCP协议:它是一个面向连接的,可靠的传输协议。该连接可抽象为一个四元组(local_ip,local_port,remote_ip,remote_port),该四元组唯一标识一个TCP连接。面向连接意味着两个通信双方(两个进程)在彼此交换数据之前必须先建立一个TCP连接。可靠性意味着双方建立的连接是可靠的,基本不会发生丢失数据的现象。总结来说TCP要点有四,一有连接,二可靠传输,三数据按照到达,四端到端流量控制。

TCP首部:


TCP报文段的首部的前20个字节是固定的,后面有4N字节是根据需要而增加的选项。因此TCP首部的最小长度时20字节。

源端口号和目的端口号:用于寻找发端和收端应用进程,不同的应用进程端口号不同。这两个值加上IP首部中的源端IP地址和目的IP地址唯一确定一个TCP连接。

有时,一个IP地址和一个端口称为一个插口(scoket)。

序号:指的是本报文段所发送的数据的第一个字节的序号。

确认号:指的是希望收到对方下一个报文段的第一个数据字节的序号。接收方只对按序到达的数据中的最高序号给出确认。例如序号31,32,33同时发送,但是31中间丢失,32,33到达,此时接收方给出的确认号仍然是31,而不能是3 2或33.

数据偏移:指的是TCP报文段的数据起始处距离TCP报文段的起始处有多远。

保留:

6个控制位的含义分别如下:

紧急URG:紧急指针字段,当URG=1时,表示系统中有紧急数据,应尽快传送,而不要按原来的排队顺序来传送。

确认ACK:仅当ACK=1时确认号字段才有效。TCP规定,在连接建立后所有传送的报文段都应把ACK置为1.

推送PSH:当两个应用进程进行交互式的通信时,有时一端的应用进程希望在键入一个命令后立即就能收到对方的响应。在这种情况下,TCP就可以使用推送操作。

复位RST:当RST=1时,表明TCP连接中出现严重错误(如由于主机崩溃或其他原因),必须释放连接,然后再重新建立运输连接。

同步SYN:在连接建立时用来同步序号。当SYN=1而ACK=0时,表明这是一个连接请求报文段。对方若同意建立连接,则应在响应的报文段中使SYN=1和ACK=1。因此,SYN=1表示这是一个连接请求报文段或者连接接收报文段。

终止FIN:用来释放一个连接。当FIN=1时,表明此报文段的发送发的数据已经发送完毕,并要求释放运输连接。

窗口:指的是发送本报文段的一方的接收窗口。窗口值告诉对方:从本报文段首部中的确认号算起,接收方目前允许对方发送的数据量。

检验和:检验范围是首部和数据部分。

紧急指针:URG=1时才有用。

 


TCP的建立与终止                                                                 

 1、TCP的建立

几乎众所周知了,TCP的建立需要三次握手,请求-应答-再次确认,才能构建一条可靠的TCP连接。具体流程详见下面的阐述:



假如客户端A想和服务器B通信,建立连接的过程分为以下三步:

第一次握手:主机A发送位码为syn=1,随机产生seq number=1234567的数据包到服务器,主机B由SYN=1知道,A要求建立联机,A进入SYN_SENT状态;

第二次握手:主机B收到请求后要确认联机信息,向A发送ack number=(主机A的seq+1),syn=1,ack=1,随机产生seq=7654321的包,B进入SYN_RCVD状态;

第三次握手:主机A收到后检查ack number是否正确,即第一次发送的seq number+1,以及位码ack是否为1,若正确,主机A会再发送ack number=(主机B的seq+1),ack=1,主机B收到后确认seq值与ack=1则连接建立成功,A进入ESTABLISHED状态。

完成三次握手,主机A与主机B开始传送数据。

 

Q1:为什么建立连接时三次握手而不是两次握手?

是为了防止失效的连接请求报文段突然又传到了服务端,因而产生错误。

Q2:SYN攻击是典型的DDOS攻击,简述其原理。

在三次握手的过程中,服务器发送SYN和ACK之后,收到客户端的ACK之前的连接成为半连接。此时服务器处于SYN_RCVD状态,收到客户端的ACK之后进入ESTABLISHED状态。SYN攻击就是利用这个时间间隔伪造大量不存在的IP地址向服务器不断发送SYN包,服务器回复确认包,并等待客户的确认。由于源地址不存在,服务器需要不断地重发直至超时,这些伪造的SYN包将长时间占用未连接队列,而正常的SYN请求被丢弃,目标系统运行缓慢,引起网络的严重瘫痪。因此大多数操作系统都闲着半连接的数量。

2TCP的终止

   由于TCP是全双工的通信模式,即通信双方都可以既是发送数据方又可以是接收数据方,因此每个方向都必须进行单独关闭,这个特点导致TCP的终止需要四次挥手。四次挥手的具体过程如下:


具体为以下四步:

1、 连接的某一方首先调用close()发起主动关闭(active close),该api会促使TCP传输层向remote peer发FIN包,这个FIN包表明发起active close一方的application不再发送数据;

2、 收到FIN包的remote peer后,在传输层针对对方的FIN包,回复一个ACK包确认(ACK的包序是在FIN包的基础上加1);

3、 应用层的application收到对方的EOF(end of file,对方的FIN包作为EOF传到应用层的application)后,得知这条连接不会有数据传输,于是也调用close()关闭连接,该close会促使传输层发送FIN包;

4、 发起主动关闭的peer的一方收到remote peer的FIN包后,回复ACK包,至此,TCP连接关闭。

这里出现的几种状态要搞清楚它们的含义:

FIN_WAIT 1:主动关闭的一方在发送FIN包后,此时该socket进入FIN_WAIT 1状态;

FIN_WAIT 2:主动关闭的一方收到对方的ACK后,进入FIN_WAIT 2. FIN_WAIT 1和FIN_WAIT 2这两种状态实际上都是在等待对方的FIN报文;

TIME_WAIT:表示收到了对方的FIN包,并发送了ACK包后的状态,也称为2MSL状态;

CLOSE_WAIT:表示正在等待关闭;

LAST_ACK:被动关闭的一方在发送FIN包后,等待对方的ACK包的时候,当收到对方的ACK包后,立马进入CLOSED状态。

Q1:为什么需要TIME_WAIT状态,即为什么需要等待2MSL?

MSL(Max Segment Life)是一个报文段在网络上最大的生存时间。

这里有两个原因需要TIME_WAIT阶段:

第一点:为实现TCP这种全双工(full-duplex)连接的可靠释放

如果客户端在发完ACK之后直接进入CLOSED状态,若由于某种原因这个ACK丢失,那么服务器由于超时将重传FIN包,而此时客户端已经关闭连接,就找不到与重发的FIN包对应的连接,最后服务器收到的将是RST而不是ACK,服务器以为是连接错误而把问题报告给上层。这样的情况虽然不会导致数据丢失,但是却导致TCP协议不可靠。因此,客户端发完ACK之后必须维护这条连接直至2MSL的时间结束。

第二点:为使旧的数据包在网络因过期而消失

若不存在TIME_WAIT阶段,若有一个新的四元组(local_ip,local_port,rempte_ip,remote_port)建立一条新的TCP连接。由于TCP协议栈是无法区分前后两条连接是否相同,在它看来,这条连接跟上一个关闭的连接使用的端口号完全相同。而等待2MSL的时间,保证网络中旧的数据包已经完全消失,这样建立新的连接时可以使用旧的端口号,避免两次连接数据错乱的情况。

Q2:为什么TCP建立连接时是三次握手,而关闭连接时是四次挥手?

这是由于TCP传输协议是全双工的原因造成的。

在建立连接时,服务器收到客户端的SYN包后,可以将应答的ACK包和同步的SYN包放在同一个报文里发送给客户端。但在关闭连接时,当收到对方的FIN包后,仅仅表示对方没有数据传给你了,并不表示你的所有数据都已经传给了对方,因此不必马上关闭SOCKET,先发送一个ACK包确认已收到对方的关闭请求。然后等你的所有数据都发送完了再发送一个FIN包给对方表示同意关闭连接,因此ACK和FIN需要分开发送,故比建立连接时多了一个交互过程。

TCP的流量控制                                     

如果发送方发送的太快,而接收方来不及接收,这样的情况就有可能导致数据丢失。所谓流量控制就是控制发送方的速率,不要让其发送的太快,使得接受方来得及接收。TCP利用滑动窗口协议实现流量控制。

滑动窗口协议允许发送方和接收方各自设置自己的缓存区大小,并且发送方在停止等待确认前可以连续发送多个分组。由于发送方不必每发一个分组就停下来等待确认,因此可以提高传输效率。

1、可变滑动窗口

设A向B发送数据,B告知A当前我的rwnd=400,那么发送方A的发送窗口不能超过接收方的接收窗口大小。注意,窗口大小的单位是字节,ACK是确认位,ack是确认序号。


由上图可知,接收方B进行了三次窗口大小设置,第一次是400,第二次是300,最后结束时是0。这里有一个问题是当B设置当前自己的接收窗口大小为0,表示不让A发送数据。A会停止等待一段时间后,等B的缓冲区大小有了富裕,就发送报文通知A可以继续发送数据了。但是这个通知报文有可能丢失,于是就出现A等待B的通知,而B等待A的数据的死锁状态。为了解决这个问题,TCP引入了坚持计时器。当A收到B的零窗口通知时,就启用该计时器,时间一到就发送一个字节的探测报文,对方在此时回应自己的窗口大小,如果仍为0,则重设计时器,继续等待,直至窗口打开。

2、传输效率

TCP使用Negle算法,它只允许一个TCP连接上最多只有一个未被确认的未完成的小分组。

TCP的四种计时器                                   

1、超时重传计时器

TCP是可靠的传输协议,在网络交互的过程中,由于TCP报文是封装在IP中的,而IP是无连接的,就可能导致报文在交互的过程中丢失。因此当TCP发送报文时,就会设置一个超时重传计时器,如果计时器溢出,还没有收到来自对方的确认,它就重传该报文。

2、坚持计时器

是为了解决零窗口大小通知时可能发生的死锁状态。

3、保活计时器

是为了防止在两个TCP连接之间出现的长时间的空闲。若客户端打开了服务器的连接,并且发送了数据,之后就保持沉默状态,也许这个客户发生了故障,但是这个连接会一直处于打开状态。因此在大多数的服务器中设置一个保活计时器,每当服务器接收到客户端的报文时,就将该计时器复位。若发送了10个探测报文时,客户端仍然无应答,则关闭该连接。

4、时间等待计时器

时间等待计时器是在终止TCP连接时的四次握手的时候使用的。时间等待计时器是用来记录2MSL这个时间的,当计时器到了2MSL,客服端才能断开连接。

TCP是如何实现可靠传输的?                         

可靠传输是TCP的一大特色,它主要从确认连接、检验数据、重新排序、丢重和流量控制这几个方面来提供可靠性的:

1、  当TCP收到对方发来的报文后,会回复一个确认包表明以已收到对方的报文。

2、  当TCP发送一个报文后,会启动一个超时重传计时器,等待对方确认收到这个报文。如果计时器溢出后未收到这个确认,那么将重传这个报文。

3、  TCP将保持它的首部和数据的检验和。这是一个端到端的检验,用以检测数据在传输过程中有无发生差错。若检验和有错,则TCP会丢弃这个报文和不回复确认,等待对方超时重传。

4、  由于TCP报文段是作为IP数据来传输的,而IP数据报的到达可能会失序,因此TCP会对数据进行重新排序,将正确顺序上交给应用层。

5、  由于IP数据会发生重复,因此TCP的接收端必须丢弃重复的数据。

6、  TCP采用流量控制使得发送端只能发送小于接收端窗口大小的报文,以防止较快主机致使较慢主机的缓冲区溢出,从而防止数据丢失。

TCPUDP的区别                                

1、  TCP是面向连接的,可靠的传输协议,虽然说网络的不稳定和不安全特性决定了无论多少次握手都不能保证可靠的传输,而TCP的三次握手在很大程度上保证了连接的可靠性;UDP是面向非连接的,在传输数据之前双方不建立连接,接收方对收到的报文不进行确认,当然发送方也不知道报文到底到达目的地没有,也不进行重发,所以UDP是不可靠的。

2、  由于1的特点导致UDP的开销小,传输效率高,实时性较好。

所以使用UDP的QQ比使用TCP的MSN传输文件较快,但并不说明QQ不安全的, 因为程序员可以手动对UDP的数据收发进行确认,比如对发送方的数据进行编号等。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值