Date: 2017-01-02 10:10:11
上一篇文章已经讲过啦TCP/IP协议族了,大概多TCP协议有了大概的了解。
在网页中HTTP请求获取内容之前是需要先建立TCP连接的,而TCP建立连接需要三次握手,该篇文章将讲解TCP的工作原理。
注意:TCP 并不能保证数据一定会被对方接收到,因为这是不可能的。TCP 能够做到的是,如果有可能,就把数据递送到接收方,否则就(通过放弃重传并且中断连接这一手段)通知用户。因此准确说 TCP 也不是 100% 可靠的协议,它所能提供的是数据的可靠递送或故障的可靠通知。
所谓三次握手(Three-way Handshake),是指建立一个 TCP 连接时,需要客户端和服务器总共发送3个包。
三次握手的目的是连接服务器指定端口,建立 TCP 连接,并同步连接双方的序列号和确认号,交换 TCP 窗口大小信息。在 socket 编程中,客户端执行 connect() 时。将触发三次握手。
重点:主要目的防止server端一直等待,浪费资源
客户端C发送请求,服务端S应答并分配资源(资源:由于不需要再次确认,这个时候服务端就会返回http请求的结果)。
若S的应答没有到达C端,C认为连接未建立,而S认为建立了,S会在一段时间内保留分配的资源
如果大量C这样请求,S会崩溃。
注意:TCP握手之后,服务端接下来是要返回客户端的请求资源哦。如果在两次握手中,客户端不断的请求,就会导致服务端大量资源的量费。
注意: 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,就重传该数据包,而不用等待超时。
在三次握手过程中,服务器发送 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协议在工作时,如果发送端的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