您好,欢迎光临本网站![请登录][注册会员]  
文件名称: TCP 详解
  所属分类: 网络基础
  开发工具:
  文件大小: 1mb
  下载次数: 0
  上传时间: 2019-07-02
  提 供 者: aba****
 详细说明:TCP是一个巨复杂的协议,因为他要解决很多问题,而这些问题又带出了很多子 问题和阴暗面。所以学习TCP本身是个比较痛苦的过程,但对于学习的过程却能 让人有很多收获。关于TCP这个协议的细节,我还是推荐你去看W.Richard Stevens的《TCP/IP 详解 卷1:协议》(当然,你也可以去读一下RFC793以及 后面N多的RFC)。另外,本文我会使用英文术语,这样方便你通过这些英文关 键词来查找相关的技术文档。TCP Flags Congestion Notification TCP Options CHse CEUA RS F ECN(Explicit Congestion 0 End of Options List Number of 32-bit words in Notification). See RFC 1 No Operation(NOP, Pad) TCP header. minimum value Congestion Window 3168 for full details, valid 2 Maximum segment size of 5. Multip y by 4 to get C Ox80 Reduced (Cwr) states below 3 Window scale byte count E 0x40 ECN Echo (ECE DSB ECN bits 4 Selective AcK ok U 0x20 Urgent 8 Timestamp RFC 793 A 0x10 Ack c01 P 0x08 Push Checksum Please refer te RFC 793 for R OxO Reset the completa Transmission S 0x02 Syn Checksum cf entire TcP Control Protocol (T cP) F oXo Fin Congestion 11 00 segment and pseudo Specification Receiver Respone 11 01 header(parts of IP header (图片来源) TcP的状态机 其实,网络上的传输是没有连接的,包括TCP也是一样的。而TCP所谓的连 接”,其实只不过是在通讯的双方维护一个“连接状态”,让它看上去好像有连接一 样。所以,TCP的状态变换是非常重要的。 下面是:“TCP协议的状态机”(图片来源)和"TCP建链接”、“TCP断链接”、“传 数据”的对照图,我把两个图并排放在一起,这样方便在你对照着看。另外,下 面这两个图非常非常的重要,你一定要记牢。(吐个槽:看到这样复杂的状态 机,就知道这个协议有多复杂,复杂的东西总是有很多坑爹的事情,所以TCP协 议其实也挺坑爹的) CLOSED Passive open set upTCB LISTEN Get Up TCD icnd syN ReceIve sY Send SyN+ACK Simutaneous open SYN-RECEWED RCCCivC SYN send AcK SYN-SENT Receive AcK Receⅳ ve staCK Send ack pen. Responder sequence ESTABLISHED Open-Initiator sequence Gloae-Initiator equence Close-Mesponder sequence ReceveR Cluse send FIN end AcK FIN-WAIT-1 CLOSE-WAIT Simultaneous Goge Receve F Receive A ck for FIN s:ndA《K Wait for Applic ation Close Send FIN FIN-WAIT-2 CLOSING LAST-ACK Receve FN Receive ack for FIN Send ack Receive acki for〃 TME-WAIT .Timer Expiration Client Server SYN SENT SYN seq=x LISTEN E(connect()) SYN seq=y, ACK=X+ 1 SYN RCVD 燃 ESTABLISHED ACK-V+ 攀业 ESTABLISHED (write()) seq=x+1 ACK=y+1 (read() ACKx FIN WAIT 1 wi close()) FIN seq=x+2 ACK=y+1 CLOSE WAIT AC FIN_WAIT_2KH FIN seq=y+ 1 LAST ACK ( close() TIME WAIT K ACK=y +2 很多人会问,为什么建链接要3次握手,断链接需要4次挥手? 对于建链接的3次握手,主要是要初始化 Sequence Number的初始 值。通信的双方要互相通知对方自己的初始化的 Sequence Number(缩写 为SN: Inital Sequence Number)所以叫SYN,全称 Synchronize Sequence Numbers。也就上图中的x和y这个号要作为以后的数据通 信的序号,以保证应用层接收到的数据不会因为网络上的传输的问题而乱 序(TCP会用这个序号来拼接数据) 对于4次挥手,其实你仔细看是2次,因为TCP是全双工的,所以,发 送方和接收方都需要Fin和Ack。只不过,有一方是被动的,所以看上去就 成了所谓的4次挥手。如果两边同时断连接,那就会就进入到 CLOSING状 态,然后到达 TIME WAIT状态。下图是双方同时断连接的示意图(你同样 可以对照着TCP状态机看) Client Server Client state server state ESTAELISHED ESTABLISHED RPCOIVP O|os口 signal From App, Receive Close send Fin signal From App, IN WA 1 FN send fw FIN-WAIl-1 Receive F From Receive FIN From client send ACK server, send ACK k* AcK CI OSING CLCSING AcK Receive AcK TINE-WAIT Receive ack TIME-WAIT Wait For double Maximum segment Life(MsL) Time Wait For b。ub|曹 Maximum Segment Life (MsL)Time CLOSED CLOSED 两端同时断连接(图片来源) 另外,有几个事情需要注意一下: 关于建连接时sYN超时。试想一下,如果 server端接到了 clien发的 SYN后回了 SYN-ACK后clen掉线了, server端没有收到 client回来的 ACK,那么,这个连接处于一个中间状态,即没成功,也没失败。于是, server端如果在一定时间内没有收到的TCP会重发 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 Food攻击。一些恶意的人就为此制造了 SYN FloOd攻击 ——给服务器发了一个SYN后,就下线了,于是服务器需要默认等635才 会断开连接,这样,攻击者就可以把服务器的syn连接的队列耗尽,让正 常的连接请求不能处理。于是, Linux下给了一个叫tp_ syncookies的参 数来应对这个事——当sYN队列满了后,TCP会通过源地址端口、目标地 址端口和时间戳打造出一个特别的 Sequence Number发回去(又叫 cookie),如果是攻击者则不会有响应,如果是正常连接,则会把这个 SYN Cookie发回来,然后服务端可以通过 cookie建连接(即使你不在SYN 队列中)。请注意,请先干万别用 tcp syncookies来处理正常的大负载的 连接的情况。因为,syη cookies是妥协版的τCP协议,并不严谨。对于正 常的请求,你应该调整三个TCP参数可供你选择,第一个是 tcp synack retries可以用他来减少重试次数;第二个是: tcp max syn backlog,可以增大SYN连接数;第三个是 tcp abort on overflow处理不过来干脆就直接拒绝连接了。 关于sN的初始化。SN是不能 hard code的,不然会出问题的—比 如:如果连接建好后始终用1来做SN,如果 clien发了30个 segmen过去, 但是网络断了,于是 client重连,又用了1做SN,但是之前连接的那些包 到了,于是就被当成了新连接的包,此时,cien的 Sequence Number可 能是3,而 Server端认为 clienti端的这个号是30了。全乱了。RFC793中 说,SN会和一个假的时钟绑在一起,这个时钟会在每4微秒对|SN做加 操作,直到超过2^32,又从0开始。这样,一个SN的周期大约是4.55个小 时。因为,我们假设我们的 TCP Segment在网络上的存活时间不会超过 Maximum Segment Lifetime(缩写为MSL- Wikipedia语条),所以,只 要MSL的值小于4.55小时,那么,我们就不会重用到|SN 关于MSL和 TIME WAIT。通过上面的SN的描述,相信你也知道 MSL是怎么来的了。我们注意到,在TCP的状态图中,从 TIME WAIT状态 到 CLOSED状态,有一个超时设置,这个超时设置是2MSL(RFC793定 义了MSL为2分钟, Linux设置成了30s)为什么要这有 TIME WAIT?为什 么不直接给转成 CLOSED状态呢?主要有两个原因:1) TIME WA|T确保 有足够的时间让对端收到了ACK,如果被动关闭的那方没有收到Ack,就 会触发被动端重发Fin,一来一去正好2个MSL,2)有足够的时间让这个 连接不会跟后面的连接混在一起(你要知道,有些自做主张的路由器会缓 存P数据包,如果连接被重用了,那么这些延迟收到的包就有可能会跟新 连接混在一起)。你可以看看这篇文章《 TIME WAIT and its design. implications for protocols and scalable client server systems 关于 TIME WAIT数量太多。从上面的描述我们可以知道, TIME WAIT是个很重要的状态,但是如果在大并发的短链接下, TIME WAIT就会太多,这也会消耗很多系统资源。只要搜一下,你就会 发现,十有八九的处理方式都是教你设置两个参数,一个叫 tcp tw_reuse,另一个叫 tcp tw recycle的参数,这两个参数默认值都 是被关闭的,后者 recyle比前者 resue更为激进, resue要温柔一些。另 外,如果使用 Itcp tw reuse,必需设置 tcp timestamps=1,否则无效。这 里,你一定要注意,打开这两个参数会有比较大的坑——可能会让TCP连 接出一些诡异的问题(因为如上述一样,如果不等待超时重用连接的话, 新的连接可能会建不上。正如宣方文档上说的一样 It should not be changed without advice/request of technical experts") 关于 tcp tw reuse。官方文档上说 tcp tw reuse加上 tcp timestamps (XAyPAWS, for Protection Against Wrapped Sequence Numbers)可以保证协议的角度上的安全,但是你需要 tcp timestamps在 两边都被打开(你可以读一下 tcp task unique的源码)。我个人估计还 是有一些场景会有问题 关于 tcp tw recycle。如果是 tcp tw recycle被打开了话,会假设对 端开启了 tcp timestamps,然后会去比较时间戳,如果时间戳变大了,就 可以重用。但是,如果对端是一个NAT网络的话(如:一个公司只用一个 P出公网)或是对端的P被另一台重用了,这个事就复杂了。建链接的 sYN可能就被直接丟掉了(你可能会看到 connection time outE的错误) (如果你想观摩一下 Linux的內核代码,请参看源 码 tcp timewait state process)。 关于 tcp max tw buckets。这个是控制并发的 ITIME WAIT的数量 默认值是180000,如果超限,那么,系统会把多的给 destory掉,然后在 日志里打一个警告(如: time wait bucket table overflow),官网文档说 这个参数是用来对抗DDoS攻击的。也说的默认值18000并不小。这个还 是需要根据实际情况考虑。 Again,使用 tcp tw_reuse和 tcp tw_ recycle来解决 TIME WAIT的问题是非常 非常危险的,因为这两个参数违反了TcP协议(RFc1122) 其实, TIME WAIT表示的是你主动断连接,所以,这就是所谓的“不作死不会 死”。试想,如果让对端断连接,那么这个破问题就是对方的了,呵呵。另外, 如果你的服务器是于HTTP服务器,那么设置一个HTTP的KeepAlive有多重要 (浏览器会重用一个TCP连接来处理多个HTTP请求),然后让客户端去断链接 (你要小心,浏览器可能会非常贪婪,他们不到万不得已不会主动断连接)。 数据传输中的 Sequence Number 下图是我从 Wireshark中截了个我在访问 coolshell.cn时的有数据传输的图给你看 下, SeqNun是怎么变的。(使用 Wireshark菜单中的 Statistics>FoW Graph.) 192168,1.192 218.245.3.166 C nt SYN 0 93 SYN ACK 223 5eg=0 Ack=1 693 ACK+ eq =1 Ack =1 图 ACK- Len: 1440 693 5∈=1Ack=1 A CK·len:14Q0 63 80=1441 Ack =1 ACK 5eg =1 Ack=1441 53 ACK·Len:144Q Sea =2881 Ack =1 93 l ACK- Len: 1440 4321Ack=1 3593 ACK Seq=1Ack=2881 PSH ACK - Len 6331 0 Seg=5761 Ack =1 ACK eg=1 Ack=4321 ACK e=1Ack=5761 693 ACK 333 eq=1Ak=6318 PSH ACK- Len: 59 3533 5e=1Ack=6318 ACK Seg=6318Ack=598 你可以看到, Seqnun的增加是和传输的字节数相关的。上图中,三次握手 后,来了两个Len:1440的包,而第二个包的seq№m就成了1441。然后第一个 ACK回的是1441,表示第一个1440收到了 注意:如果你用 Wireshark抓包程序看3次握手,你会发现 SeqNun总是为0,不 是这样的, Wireshark为了显示更友好,使用了 Relative SeqNum相对序 号,你只要在右键菜单中的 protocol preference中取消掉就可以看到" Absolute SegNum”了 TCP重传机制 TCP要保证所有的数据包都可以到达,所以,必需要有重传机制。 注意,接收端给发送端的Aαk确认只会确认最后一个连续的包,比如,发送端发 了1,2,3,4,5—共五份数据,接收端收到了1,2,于是回ack3,然后收到了4(注 意此时3没收到),此时的TCP会怎么办?我们要知道,因为正如前面所说的, SeqNum和Ack是以字节数为单位,所以ack的时候,不能跳着确认,只能确认 最大的连续收到的包,不然,发送端就以为之前的都收到了 超时重传机制 一种是不回ack,死等3,当发送方发现收不到3的ack超时后,会重传3。一旦接 收方收到3后,会ack回4—意味着3和4都收到了。 但是,这种方式会有比较严重的问题,那就是因为要死等3,所以会导致4和5即 便已经收到了,而发送方也完全不知道发生了什么事,因为没有收到Ack,所 以,发送方可能会悲观地认为也丢了,所以有可能也会导致4和5的重传。 对此有两种选择 一种是仅重传 timeout的包。也就是第3份数据。 另—种是重传 timeout后所有的数据,也就是第3,4,5这三份数据。 这两种方式有好也有不好。第一种会节省带宽,但是慢,第二种会快一点,但是 会浪费带宽,也可能会有无用功。但总体来说都不好。因为都在等 timeout, timeou可能会很长(在下篇会说TCP是怎么动态地计算出 timeout的) 快速重传机制 于是,TCP引入了一种叫 Fast retransmit的算法,不以时间驱动,而以数据驱 动重传。也就是说,如果,包没有连续到达,就ack最后那个可能被丟了的包, 如果发送方连续收到3次相同的ack,就重传。 Fast Retran的好处是不用等 timeout了再重传。 比如:如果发送方发出了1,2,3,4,5份数据,第一份先到送了,于是就ack 回2,结果2因为某些原因没收到,3到达了,于是还是ack回2,后面的4和5都到 了,但是还是ack回2,因为2还是没有收到,于是发送端收到了三个ack=2的确 认,知道了2还没有到,于是就马上重转2。然后,接收端收到了2,此时因为 3,4,5都收到了,于是ack回6。示意图如下: Seg 12345 k ACK 2 ACK 2 ACK 2 ““…· ACK 2 判ACK6 Se ender Receiver
(系统自动生成,下载前可以参看下载内容)

下载文件列表

相关说明

  • 本站资源为会员上传分享交流与学习,如有侵犯您的权益,请联系我们删除.
  • 本站是交换下载平台,提供交流渠道,下载内容来自于网络,除下载问题外,其它问题请自行百度
  • 本站已设置防盗链,请勿用迅雷、QQ旋风等多线程下载软件下载资源,下载后用WinRAR最新版进行解压.
  • 如果您发现内容无法下载,请稍后再次尝试;或者到消费记录里找到下载记录反馈给我们.
  • 下载后发现下载的内容跟说明不相乎,请到消费记录里找到下载记录反馈给我们,经确认后退回积分.
  • 如下载前有疑问,可以通过点击"提供者"的名字,查看对方的联系方式,联系对方咨询.
 相关搜索: TCP详解
 输入关键字,在本站1000多万海量源码库中尽情搜索: