TCP协议连接建立时3次握手的过程。
简述TCP协议连接建立时3次握手的过程。 根据TCP头部,说明下列3个包在连接建立过程中的次序. 0020 00 50 83 aa 46 49 3e dd 33 96 37 a3 a0 12 ...P..FI>.3.7... 0030 16 a0 c4 c0 00 00 02 04 05 b4 04 02 08 0a d7 9b ................ 0040 62 b7 00 56 4a 2a 01 03 03 02 b..VJ*.... (1) 0020 83 aa 00 50 33 96 37 a2 00 00 00 00 a0 02 .....P3.7....... 0030 16 d0 84 1d 00 00 02 04 05 b4 04 02 08 0a 00 56 ...............V 0040 4a 2a 00 00 00 00 01 03 03 00 J*........ (2) 0020 83 aa 00 50 33 96 37 a3 46 49 3e de 80 10 .....P3.7.FI>... 0030 16 d0 f3 4b 00 00 01 01 08 0a 00 56 4a 36 d7 9b ...K.......VJ6.. 0040 62 b7 b. (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状态,等待服务器确认; tcp-断开连接:
|
主要部分,四次握手: 断开连接其实从我的角度看不区分客户端和服务器端,任何一方都可以调用close(or closesocket)之类 当被动关闭的一方收到FIN报文时,它会发送ACK确认报文(对于ACK这个东西你应该很熟悉了)。这里有个 我可以告诉你,一旦当你调用close(or closesocket),这一端就会发送FIN报文。也就是说,现在被动 在前面的文章中,我一直没提TCP的状态转换。在这里我还是在犹豫是不是该将那张四处通用的图拿出来, 给出一个正常关闭时的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
补充细节: 关于以上的四次握手,我补充下细节: 2. 发送了FIN只是表示这端不能继续发送数据(应用层不能再调用send发送),但是还可以接收数据。 3. 应用层如何知道对端关闭?通常,在最简单的阻塞模型中,当你调用recv时,如果返回0,则表示对端 4. 在很多时候,TCP连接的断开都会由TCP层自动进行,例如你CTRL+C终止你的程序,TCP连接依然会正常关
特别的TIME_WAIT状态: 从以上TCP连接关闭的状态转换图可以看出,主动关闭的一方在发送完对对方FIN报文的确认(ACK)报文后, 什么是2MSL?MSL即Maximum Segment Lifetime,也就是报文最大生存时间,引用<TCP/IP详解>中的话:“ 为什么需要2MSL?根据<TCP/IP详解>和<The TCP/IP Guide>中的说法,有两个原因: TIME_WAIT状态所带来的影响: 当某个连接的一端处于TIME_WAIT状态时,该连接将不能再被使用。事实上,对于我们比较有现实意义的 对于服务器而言,如果服务器突然crash掉了,那么它将无法再2MSL内重新启动,因为bind会失败。解决这 对于TIME_WAIT的插曲: 当建立一个TCP连接时,服务器端会继续用原有端口监听,同时用这个端口与客户端通信。而客户端默认情况 对于服务器端,当设置了SO_REUSEADDR选项时,它可以在2MSL内启动并listen成功。但是对于客户端,当使 要解决windows平台的这个问题,可以设置SO_LINGER选项。SO_LINGER选项决定调用close时,TCP的行为。 如你所见,这样做虽然解决了问题,但是并不安全。通过以上方式设置SO_LINGER状态,等同于设置SO_DONTLINGER 断开连接时的意外: 这似乎可以通过设置SO_KEEPALIVE选项来解决,不过不知道这个选项是否对于所有平台都有效。 |