TCP协议大全

版权声明:本文为博主原创文章,转载需注明出处. https://blog.csdn.net/piaoslowly/article/details/81909784

Date: 2017-01-02 10:10:11

TCP协议笔记

上一篇文章已经讲过啦TCP/IP协议族了,大概多TCP协议有了大概的了解。
在网页中HTTP请求获取内容之前是需要先建立TCP连接的,而TCP建立连接需要三次握手,该篇文章将讲解TCP的工作原理。

TCP特性

  • TCP提供一种面向连接的、可靠的字节流服务
  • 在一个TCP连接中,仅有两方进行彼此通信。广播和多播不能用于TCP
  • TCP使用校验和,确认和重传机制来保证可靠传输
  • TCP给数据分节进行排序,并使用累积确认保证数据的顺序不变和非重复
  • TCP使用滑动窗口机制来实现流量控制,通过动态改变窗口的大小进行拥塞控制

注意:TCP 并不能保证数据一定会被对方接收到,因为这是不可能的。TCP 能够做到的是,如果有可能,就把数据递送到接收方,否则就(通过放弃重传并且中断连接这一手段)通知用户。因此准确说 TCP 也不是 100% 可靠的协议,它所能提供的是数据的可靠递送或故障的可靠通知。

TCP三次握手连接

所谓三次握手(Three-way Handshake),是指建立一个 TCP 连接时,需要客户端和服务器总共发送3个包。
三次握手的目的是连接服务器指定端口,建立 TCP 连接,并同步连接双方的序列号和确认号,交换 TCP 窗口大小信息。在 socket 编程中,客户端执行 connect() 时。将触发三次握手。

  1. 客户端向服务器发送SYN报文(Seq=x, SYN=1),客户端进去SYN_SENT状态
  2. 服务器收到客户端的请求,向客户端回复一个确认信息(Ack = x + 1)和 一个SYN包(seq=y)建立连接请求,此时服务器进去SYN_RECV状态
  3. 客户端收到服务器的回复(SYN+ACK报文),向服务器端发送ACK,此包发送完毕后客户端和服务器端进入ESTABLISHED状态

先看一下TCP的头部

第一次握手

第二次握手

第三次握手

为什么要三次握手而不是二次

重点:主要目的防止server端一直等待,浪费资源

  1. 三次握手的目的是同步连接双方的序列号和确认号并交换TCP窗口大小信息。
  2. 两次握手可能因为丢包而出现死锁。

客户端C发送请求,服务端S应答并分配资源(资源:由于不需要再次确认,这个时候服务端就会返回http请求的结果)。
若S的应答没有到达C端,C认为连接未建立,而S认为建立了,S会在一段时间内保留分配的资源
如果大量C这样请求,S会崩溃。

注意:TCP握手之后,服务端接下来是要返回客户端的请求资源哦。如果在两次握手中,客户端不断的请求,就会导致服务端大量资源的量费。

TCP四次挥手断开

  1. 客户端A发送位码为FIN=1,用来关闭客户A到服务器B的数据传送。此时A的状态为FIN_WAIT_1
  2. 服务器B收到这个FIN,它发回一个ACK,确认序号为收到的序号加1。此时A为FIN_WAIT_2,B为CLOSE_WAIT
  3. 服务器B关闭与客户端A的连接,发送一个FIN给客户端A。此时A为TIME_WAIT,B为LAST_ACK
  4. 客户端A发回ACK报文确认,并将确认序号设置为收到序号加1。此时A、B都关闭了,状态变为CLOSED。
    说明:关闭分为两部分,客户端发器关闭,服务端响应;服务端发器关闭,客户端响应。

注意: 2,3阶段可以一起发送哦,如果2,3阶段一起发送,客户端A直接进入到TIME_WAIT状态,无须进入FIN_WAIT_2。
2,3阶段分别发送的是ACK,FIN,如果服务端还有未传输完毕的数据就单独发送一个ACK应答客户端发送过来的FIN;等待传送完毕再发送一个FIN告诉客户段A服务端B也可以断开连接了。但是如果服务端在接受到客户端A的FIN时,已经传送完毕数据了,那就可以ACK,FIN一起发送了,没必要让客户端A进入FIN_WAIT2等候了。参考文献

图中有个TIME_WAIT是干什么的?
持续时间未2MSL,一个数据包在网络中的最长生存时间为MSL 。 假设最后客户端回复的ACK丢失,服务器端会在超时时间到来时,重传最后一个FIN包。
ACK和FIN在网络中的最长生存时间就为2MSL,这样就可以可靠的断开TCP的双向连接。

MSL是Maximum Segment Lifetime英文的缩写,中文可以译为“报文最大生存时间”,他是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。RFC 793中规定MSL为2分钟,实际应用中常用的是30秒,1分钟和2分钟等。

为什么建立连接需要三次握手,而断开连接需要四次握手

为什么需要三次握手?
为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误。
client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。(和上面的例子差不多,两种不同的场景,都是客户端收不到或者不需要的情况下服务端还发送资源)

为什么需要四次连接断开?
因为客户端和服务端都需要一个FIN和ACK,当客户端发送了FIN包之后,处于半关闭状态,此时仍然可以接收数据包。
在断开连接时,如果服务端收到FIN包,但此时仍有数据未发送完,此时就需要先向客户端回复ACK,告诉客户端我已经收到你的请求了。等到将剩下的数据都发送完之后,再向客户端发送FIN,断开发送方向的连接,因此很多时候FIN和ACK需要在两个数据包中发送,因此需要四次握手。

超时重传和快速重传

超时重传:当超时时间到达时,发送方还未收到对端的ACK确认,就重传该数据包。
快速重传:当后面的序号先到达,如接收方接收到了1、 3、 4,而2没有收到,接收方就会立即向发送方重复发送三次ACK=2的确认请求重传。如果发送方连续收到3个相同序号的ACK,就重传该数据包,而不用等待超时。

TCP之SYN攻击

在三次握手过程中,服务器发送 SYN-ACK 之后,收到客户端的 ACK 之前的 TCP 连接称为半连接(half-open connect)。此时服务器处于 SYN_RCVD 状态。当收到 ACK 后,服务器才能转入 ESTABLISHED 状态.

SYN 攻击指的是,攻击客户端在短时间内伪造大量不存在的IP地址,向服务器不断地发送SYN包,服务器回复确认包,并等待客户的确认。由于源地址是不存在的,服务器需要不断的重发直至超时,这些伪造的SYN包将长时间占用未连接队列,正常的SYN请求被丢弃,导致目标系统运行缓慢,严重者会引起网络堵塞甚至系统瘫痪。SYN 攻击是一种典型的 DoS/DDoS 攻击。

在 Linux/Unix 上可以使用系统自带的 netstats 命令来检测 SYN 攻击。

防范措施:
1、降低SYN timeout时间,使得主机尽快释放半连接的占用
2、采用SYN cookie设置,如果短时间内连续收到某个IP的重复SYN请求,则认为受到了该IP的攻击,丢弃来自该IP的后续请求报文
3、在网关处设置过滤,拒绝将一个源IP地址不属于其来源子网的包进行更远的路由

TCP与UDP的区别

  • TCP是有连接的,两台主机在进行数据交互之前必须先通过三次握手建立连接;而UDP是无连接的,没有建立连接这个过程
  • TCP是可靠的传输,TCP协议通过确认和重传机制来保证数据传输的可靠性;而UDP是不可靠的传输
  • TCP还提供了拥塞控制、滑动窗口等机制来保证传输的质量,而UDP都没有
  • TCP是基于字节流的,将数据看做无结构的字节流进行传输,当应用程序交给TCP的数据长度太长,超过MSS时,TCP就会对数据进行分段,因此TCP的数据是无边界的;而UDP是面向报文的,无论应用程序交给UDP层多长的报文,UDP都不会对数据报进行任何拆分等处理,因此UDP保留了应用层数据的边界

基于TCP协议与UDP协议

  • TCP: FTP、HTTP、Telnet、SMTP、POP3、HTTPS
  • UDP:DNS、SNMP、NFS

TCP窗口滑动以及拥塞控制

TCP协议在工作时,如果发送端的TCP协议软件每传输一个数据分组后,必须等待接收端的确认才能够发送下一个分组,由于网络传输的时延,将有大量时间被用于等待确认,导致传输效率低下。为此TCP在进行数据传输时使用了滑动窗口机制。
TCP滑动窗口用来暂存两台计算机间要传送的数据分组。每台运行TCP协议的计算机有两个滑动窗口:一个用于数据发送,另一个用于数据接收。发送端待发数据分组在缓冲区排队等待送出。被滑动窗口框入的分组,是可以在未收到接收确认的情况下多送出的部分。滑动窗口左端标志X的分组,是已经被接收端确认收到的分组。随着新的确认到来,窗口不断向右滑动。
TCP协议软件依靠滑动窗口机制解决传输效率流量控制问题。

这部分没法模拟,所以只能复制粘贴。详情查看解说

参考文章

https://hit-alibaba.github.io/interview/basic/network/TCP.html
http://blog.csdn.net/u012658346/article/details/51192944
http://www.cnblogs.com/wulala1119/p/4749892.html
http://blog.csdn.net/longwang155069/article/details/50058779

猜你喜欢

转载自blog.csdn.net/piaoslowly/article/details/81909784