TCP连接建立与终止过程剖析.ppt_第1页
TCP连接建立与终止过程剖析.ppt_第2页
TCP连接建立与终止过程剖析.ppt_第3页
TCP连接建立与终止过程剖析.ppt_第4页
TCP连接建立与终止过程剖析.ppt_第5页
已阅读5页,还剩17页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1,TCP连接建立与终止过程剖析,性能测试组:凌宏立 2012-05-27,目录,TCP连接建立与终止过程剖析,2,案例,3,基础知识,1,网络模型,TCP协议特点,面向流的投递服务,面向连接的投递服务,TCP特性,可靠性传输,全双工传输,TCP报文格式,1、源端口和目的端口各占16位,每台电脑开启的端口数为 216= 65536 2、顺序号(SEQ),当一方要与另一方联系时就发送一个初始序号(ISN)给对方,TCP连接是 全双工的,即双方的数据流可同时传输。在传输过程中双方数据是独立的,因此每个TCP连接 必须有两个顺序号分别对应不同方向的数据流。ISN随时间而变化,可看作32位计数器,每4ms加1 3、确认序(ACK),在握手阶段,确认序号将发送方的序号加1作为回答,在数据传输 阶段,确认序号将发送方的序号加发送的数据大小作为回答,表示确实收到这些数据。,TCP报文格式,6个标志位: U R G 紧急指针,用来保证TCP连接不被中断,并且督促中间层设备要尽快处理这些数据。 A C K 确认序号有效。 P S H 接收方应该尽快将这个报文段交给应用层,缩写为P。 R S T 重建连接,缩写为R。 S Y N 同步序号用来发起一个连接,缩写为S。 F I N 发端完成发送任务,缩写为F。,连接建立,4:1069,5:53,客户端,服务端,(主动打开)SYN_SEND,ESTABLISHED,SYN_RCVD,LISTEN(被动打开),ESTABLISHED,SYN (SEQ=X),ACK Y+1,SYN (SEQ=Y ACK= X+1),1、请求端(通常称为客户)发送一个SYN段指明客户打算连接的服务器的端口,以及初始序号(ISN),这个S Y N段为报文段1。 2、服务器发回包含服务器的初始序号的SYN报文段(报文段2)作为应答。同时,将ACK确认序号设置为客户的I S N加1以对客户的SYN报文段进行确认。一个SYN将占用一个序号。 3、客户必须将ACK确认序号设置为服务器的ISN加1以对服务器的SYN报文段进行确认(报文段3),总结: 客户端:SYN_SENT -ESTABLISHED 服务端:LISTEN-SYN_RECV -ESTABLISHED,连接建立超时,TCP-IP详解卷1:服务器断开时,客户端会每隔多长时间尝试重新发送SYN建立连接? 第二个SYN与第一个SYN的间隔时间是5.8秒,第三个与第二个的间隔时间是24秒(已过时),Linux 2.5以上版本已经改变了连接建立超时算法,目前每次重新发送SYN的间隔时间为: 3 x 2n (n = 0) Linux源码:http:/lxr.linux.no/#linux+v3.2.6/net/ipv4/tcp_timer.c#L141,总结: 1、超时间隔:第二个与第一个相隔3s,第三个与第二个相隔6s,第四个与第三个相隔12s,即3 x 2n (n = 0) 2、服务器断开连接,客户端最多会发送6次SYN请求(即重试5次),若仍无法连接,则中断请求。 PS: 通过tcp_syn_retries :INTEGER修改内核参数设置发送多少个 SYN 连接请求才决定放弃,不应该大于255 (roottest1 # sysctl -a | grep tcp_syn_retries 查看默认值),连接终止,客户端,服务端,TIME_WAIT,CLOSED,LAST_ACK,CLOSE_WAIT(被动关闭),FIN_WATI_2,FIN M,ACK M+1,(主动关闭)FIN_WAIT_1,FIN N,ACK N+1,TIME_WAIT也称2MSL等待状态。每个具体TCP实现必须选择一个报文段最大生存时间MSL,它是任何报文段被丢弃前在网络内的最长时间。RFC793指出MSL为2min,然而不同的系统实现会不太一样,常用30s、1min或2min,总结: 1、发送的第一个Fin包一定会带上一个Ack, 该ACK为重发最近一次的Ack,回应最接近的一个包 2、大多数TCP实现加了限制,在2MSL等待期间的端口不允许重新使用,为了让一个进程重新使 用处于2MSL等待状态的本地端口,可以在代码中加入SO_REUSEADDR选项 3、快速回收和重用2MSL状态的端口,可优化Linux内核参数,在/etc/sysctl.conf中加入面内容: net.ipv4.tcp_tw_reuse = 1 /开启重用 net.ipv4.tcp_tw_recycle = 1 /快速回收 PS: 网维经验:在网络慢的环境(如移动网关),会导致与服务器建立连接异常,在局域网内可设置。 4、若想修改TIME_WAIT的超时时长,需重新编译Linux内核,同时打开,(主动打开)SYN_SEND,ESTABLISHED,SYN_RCVD,SYN_SEND(主动打开),SYN_RCVD,ESTABLISHED,SYN J,SYN K,SYN K,ACK J+1,SYN J,ACK K+1,1、在A机器运行死循环脚本,尝试与B服务器的8888端口建立连接,2、通过tcpdump查看数据包,3、在B机器运行死循环脚本,尝试与A服务器的7777端口建立连接,同时打开,总结: 1、同时打开的连接需要交换4个报文,比正常的三次握手多一个,同时双方没有客户端和服 务端之分,每一端既是客户端又是服务端。 2、同时打开连接跟正常三次握手连接一样仅建立一条连接而不是两条连接。,数据包:,PS: 同时打开还是正常握手? 1. tcpdump抓包的结果反映的是正常三次握手,也就是非真正的同时打开? 2. 是同时打开,但是最后的ACK包还是会发,只不过在发之前已经是连接建立的状态? 分析:假设上面为正常的三次握手,那么两个ACK数据包应该上面,而非最后面,若最后面,则说明前面四个S发完后,双方已经进入了ESTABLISHED状态,从而推出应该是同时打开。因此,同时打开,即使两端已经建立了ESTABLISHED,但还是会发送最后的ACK(注:TCP/IP卷1未明确说明否会发送ACK),半打开,如果一方已经关闭或异常终止连接而另一方却还不知道,这样的TCP连接称为半打开(Half-Open)。,总结: 任何一端的主机异常都可能导致发生这种情况,只要不在半打开连接上传输数据,仍处于连接状态的一方就不会检测到另一方已经出现异常。导致出现半打开连接现象的常见原因有:主机断电,主机重启,程序突然结束等等,1、在p7上启动服务,端口为7878,在p5中运行telnet程序,通过它与p7上的服务器建立连接,然后 键入一行字符。 2、接着断开服务器主机与以太网电缆,并重启服务器主机,这可以模拟服务器主机出现异常。 (在重启服务器之前断开以太网电缆是为了防止它向打开的连接发送FIN, 某些TCP在关机的时候会这么做) 3、服务器主机重启后,重新接上电缆,并从客户端向服务器发送另一行字符。 4、由于服务器的TCP已重新启动,它将丢失复位前连接的所有信息,因此它不知道数据包中提到的连接, TCP的处理是服务器以复位RST作为应答。,同时关闭,(主动关闭)FIN_WAIT_1,TIME_WAIT,CLOSING,FIN_WAIT_1(主动关闭),CLOSING,TIME_WAIT,FIN J,FIN K,ACK J+1,ACK K+1,1、若客户端和服务端同时发送FIN执行主动关闭,则为同时关闭。 2、同时关闭和正常关闭发送的数据包数目相同,只是顺序不同。,客户端,服务端,半关闭,1、TCP半关闭提供了连接的一端在结束它的发送后还能接收来自另一端数据的能力 2、AB A发送一个FIN给B,B收到A的FIN,只意味着从A向B发送数据的通道停止了,没有 数据流动,但B到 A的通道仍然没有停止,B仍然可以发送数据给A,总结: 为什么TCP建立一个连接需要三次握手,而终止一个连接需要经过四次握手? 半关闭,主机A,主机B,FIN(SEQ=x),ACK(SEQ=y, ACK=x+1),A-B单向连接释放,但A仍能接收B的数据,ACK(SEQ=y,ACK=x+1),FIN(SEQ=x),B-A单向连接释放,半关闭,Linux的rsh(remote shell)命令即采用TCP的半关闭特性实现,rsh,localhost,datafile,标准输入,sort,TCP连接,标准输出,终端,2,1、localhost和82建立TCP连接(牢记:TCP连接是全双工的) 2、所有的原始数据(datafile)通过TCP连接从rsh客户端传送到sort服务器进行排序 3、当输入(datafile)到达文件尾时,rsh客户端执行这个TCP连接的半关闭 4、sort服务器在它的标准输入(TCP连接)上收到一个文件结束符,对数据进行排序, 并将结果写在它的标准输出上(TCP连接) 5、rsh客户端继续接收来自TCP连接另一端的数据,并将排序的文件复制到它的标准输出上,TCP内核参数优化,tcp_syn_retries = INTEGER 对于一个新建连接,修改内核参数设置,内核要发送多少个 SYN连接请求才决定放弃,不应该大于255(默认5次) tcp_synack_retries = INTEGER 对于远端的连接请求SYN,内核会发送SYN ACK数据报,以确认收到上一个 SYN连接请求包(默认5次) tcp_fin_timeout = INTEGER 对于本端断开的socket连接,TCP保持在FIN-WAIT-2状态的时间。对方可能会断开连接或一直不结束连接或不可预料的进程死亡(默认60 秒) tcp_tw_recycle = BOOLEAN 设置为1,打开快速 TIME-WAIT sockets 回收(默认0) tcp_tw_reuse = BOOLEAN 该文件表示是否允许重新应用处于TIME-WAIT状态的socket用于新的TCP连接(默认为0) tcp_max_tw_buckets = INTEGER 系统在同时所处理的最大 timewait sockets 数目。如果超过此数的话time-wait socket 会被立即砍除并且显示警告信息(默认180000) tcp_max_syn_backlog = 8192 SYN队列的长度,加大队列长度为8192,可以容纳更多等待连接的网络连接数(默认1024) net.ipv4.ip_local_port_range = 10000 65000 表示用于向外连接的端口范围,改为10000到65000 (默认 32768到61000),TCP完整状态变迁图,发生在身边的案例,案例一:TCP延迟确认(Delay ACK),TCP延迟确认机制导致的问题曾发生在网盘,开放平台项目,乐园等项目,图二比图一少了一个报文,减少了网络中的数据包,避免网络拥塞,这是延迟ACK确认的目的。,客户端,服务端,报文一,报文三,报文二,报文四,数据字节,数据字节的确认,数据字节的回显,回显字节的确认,客户端,服务端,报文1,报文2,报文3,数据字节,数据字节回显、确认,回显字节的确认,图一:正常,图二:Delay ACK,总结: 1、当客户端发送SYN时,数据包小于132字节时,如果客户端未设置TCP_NODELAY时,服务器会延迟40ms后再进行ACK确认 2、TCP-IP详解卷1:TCP延迟确认机制默认延迟200ms(已过时),Linux 2.6.18以上的版本Dealy ACK默认延迟时间修改为40ms,案例一:TCP延迟确认(Delay ACK),代码中可采用下面的方式来解决TCP延迟确认的方法,c+:在recv系统调用后,调用一次setsockopt函数,设置TCP_QUICKACK,Java:在创建socket后,设置TcpNoDelay为true,案例二:TCP中time_wait状态过多问题,TIME_WAIT的产生:主动先发FIN的就可能进入TIME_WAIT状态(注:无客户端和服务器之分) 引入TIME_WAIT的原因:当TCP执行一个主动关闭,并发送最后一个ACK,该连接必须在TIME_WAIT状态停留的时间为2倍的MSL,这样就可让TCP再次发送最后的ACK已防止这个ACK丢失(另一端超时或重发最后的FIN),说明: net.ipv4.tcp_tw_reuse = 1 表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭。可以降低本地端口耗尽出现的概率,从而降低负载。 net.ipv4.tcp_tw_recycle = 1 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。会加速TIME_WAIT的回收,从而显著降低系统中TIME_WAIT状态的socket数量。 net.ipv4.tcp_max_tw_buc

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论