TCP/IP创建与断开链接详细过程
TCP协议链接创建时3次握手的过程。 html
简述TCP协议链接创建时3次握手的过程。 服务器
根据TCP头部,说明下列3个包在链接创建过程当中的次序. 网络
002000 50 83 aa
46 49 3e dd 33 96 37 a3 a0 12...P..FI>.3.7... socket
003016 a0 c4 c0 00 00 02 04 05 b4
04 02 08 0a d7 9b................ tcp
004062 b7 00 56 4a 2a 01 03 03
02b..VJ*....(1) ide
002083 aa 00 50
33 96 37 a2 00 00 00 00 a0 02.....P3.7....... 函数
003016 d0 84 1d 00 00 02 04 05 b4
04 02 08 0a 00 56...............V 优化
00404a 2a 00 00 00 00 01 03 03
00J*........(2) ui
002083 aa 00 50
33 96 37 a3 46 49 3e de 80 10.....P3.7.FI>... url
003016 d0 f3 4b 00 00 01 01 08 0a
00 56 4a 36 d7 9b...K.......VJ6..
004062
b7b.
(3)
解:
在TCP/IP协议中,TCP协议提供可靠的链接服务,采用三次握手创建一个链接。
1)是第二次握手,flags位上为12,二进制是0001 0010,即表示有syn和ack.
2)是第一次握手,flags位上为02,二进制是0000 0010,即表示有syn没有ack。
3)是第三次握手,flags位上为10,二进制是0001 0000,即表示有ack没有syn。
该链接访问的是80端口,是为HTTP(HyperText Transport Protocol,超文本传输协议)开放的,
第一次握手:创建链接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时本身也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
完成三次握手,客户端与服务器开始传送数据。
tcp-断开链接:
主要部分,四次握手: 断开链接其实从个人角度看不区分客户端和服务器端,任何一方均可以调用close(or closesocket)之类 的函数开始主动终止一个链接。这里先暂时说正常状况。当调用close函数断开一个链接时,主动断开的 一方发送FIN(finish报文给对方。有了以前的经验,我想你应该明白我说的FIN报文时什么东西。也就是 一个设置了FIN标志位的报文段。FIN报文也可能附加用户数据,若是这一方还有数据要发送时,将数据附 加到这个FIN报文时彻底正常的。以后你会看到,这种附加报文还会有不少,例如ACK报文。咱们所要把握 的原则是,TCP确定会力所能及地达到最大效率,因此你可以想到的优化方法,我想TCP都会想到。 当被动关闭的一方收到FIN报文时,它会发送ACK确认报文(对于ACK这个东西你应该很熟悉了)。这里有个 东西要注意,由于TCP是双工的,也就是说,你能够想象一对TCP链接上有两条数据通路。当发送FIN报文 时,意思是说,发送FIN的一端就不能发送数据,也就是关闭了其中一条数据通路。被动关闭的一端发送 了ACK后,应用层一般就会检测到这个链接即将断开,而后被动断开的应用层调用close关闭链接。 我能够告诉你,一旦当你调用close(or closesocket),这一端就会发送FIN报文。也就是说,如今被动 关闭的一端也发送FIN给主动关闭端。有时候,被动关闭端会将ACK和FIN两个报文合在一块儿发送。主动 关闭端收到FIN后也发送ACK,而后整个链接关闭(事实上还没彻底关闭,只是关闭须要交换的报文发送 完毕),四次握手完成。如你所见,由于被动关闭端可能会将ACK和FIN合到一块儿发送,因此这也算不上 严格的四次握手---四个报文段。 在前面的文章中,我一直没提TCP的状态转换。在这里我仍是在犹豫是否是该将那张四处通用的图拿出来, 不过,这里我只给出断开链接时的状态转换图,摘自<The TCP/IP Guide>: 给出一个正常关闭时的windump信息: 14:00:38.819856 IP cd-zhangmin.1748 > 220.181.37.55.80: F 1:1(0) ack 1 win 65535 14:00:38.863989 IP 220.181.37.55.80 > cd-zhangmin.1748: F 1:1(0) ack 2 win 2920 14:00:38.864412 IP cd-zhangmin.1748 > 220.181.37.55.80: . ack 2 win 65535 补充细节: 关于以上的四次握手,我补充下细节: 1. 默认状况下(不改变socket选项),当你调用close( or closesocket,如下说close再也不重复)时,若是 发送缓冲中还有数据,TCP会继续把数据发送完。 2. 发送了FIN只是表示这端不能继续发送数据(应用层不能再调用send发送),可是还能够接收数据。 3. 应用层如何知道对端关闭?一般,在最简单的阻塞模型中,当你调用recv时,若是返回0,则表示对端 关闭。在这个时候一般的作法就是也调用close,那么TCP层就发送FIN,继续完成四次握手。若是你不调用 close,那么对端就会处于FIN_WAIT_2状态,而本端则会处于CLOSE_WAIT状态。这个能够写代码试试。 4. 在不少时候,TCP链接的断开都会由TCP层自动进行,例如你CTRL+C终止你的程序,TCP链接依然会正常关 闭,你能够写代码试试。 特别的TIME_WAIT状态: 从以上TCP链接关闭的状态转换图能够看出,主动关闭的一方在发送完对对方FIN报文的确认(ACK)报文后, 会进入TIME_WAIT状态。TIME_WAIT状态也称为2MSL状态。 什么是2MSL?MSL即Maximum Segment Lifetime,也就是报文最大生存时间,引用<TCP/IP详解>中的话:“ 它(MSL)是任何报文段被丢弃前在网络内的最长时间。”那么,2MSL也就是这个时间的2倍。其实我以为没 必要把这个MSL<span STYLE="FonT-siZe: 10pt; CoLor: black; FonT-FAMiLY: 宋体; mso-bidi-font-family: Arial; mso-font-kerning: 0pt; mso-asc |