学习主要内容:
1.TCP三路握手和四路握手
2.TCP的常见标识以及监听端口的状态
先模拟一个场景,“向东A"有一亲密基友“攀攀B”,一天A晚上想约B 出去溜冰,由于地理原因,就选择打电话通知
......两人经过各自身份确认后才会进行下面的秘密交谈. TCP 的三路握手连接也是这样的....
三路握手
以下为三路握手的整个过程:
1.服务器必须准备好接受外来连接。通常调用的是socket,bind和listen这三个函数来完成。我们称之为被动打开(passive open).完成服务器将监听端口状态为:
listen
2.客户端通过connect 发起主动打开(active open)向指定地址服务端发送一个
SYN分节,和初始化
序列号
3.服务器必须确认(ACK)客户端的SYN,同时自己也要发送一个SYN分节。
4.客户端必须确认服务器的SYN
这样交换至少三个分组,因此称之为TCP三路握手
在此过程中,客户端和服务端都会开启一个端口进行消息传送,同时它们的端口状态也在放生不同状态转换
客户端口转换过程
客户端:
closed
-----发送SYN---->
SYN_SENT
----接受到SYN ACK-->
ESTABLISHED
----发送ACK--->
服务端口转换过程
服务端:
listen -----接收到SYN---->
SYN_RCVD---发送SYN ACK--->
SYN_RCVD----------接受ACK---->
ESTABLISHED
有开始就有结束,既然有了连接就一定有关闭连接。TCP 连接的终结者---四路握手
四路握手
TCP 建立连接需要3个分节,终止一个连接则需要4个分节
以下为四路握手的整个过程:
1.应用进程调用了close函数.我们称该端执行了
“主动关闭”(无论客户端和服务端,调用close函数就是主动关闭,提出主动关闭的一端是需要付出代价的,等待2个MSL时间).该端发送一个FIN分节表示数据发送完毕.
2.接受到FIN的对端
执行
“被动关闭”,这个FIN是由TCP确认,FIN的接受也作为一个文件接受符传递给接受端应用进程,意味着接受端应用进程在相应连接上再无数据可接受
3.一段时间后,接受到这个文件结束符的应用进行将调用close关闭它的套接字,这导致它的TCP也发送一个FIN
4.最后接受这个最终FIN的原发送端TCP(执行主动关闭那一端)确认这个FIN。
引自Unix网络编程图片如下:
.....................理想很丰满,但现实很骨感.....................
我用wireshark 进行了多次测试........显示内容大概如下:
简单分析下: 9339端口向 61544发送 FIN ACK 序列号 73
61544 端口 响应 9339端口 ACK (为什么这么确定? ACK:74= Seq:73 +1)
61544 端口 同样向9339端口 发送 FIN ACK
最后 9339端口 响应 ACK 給61544
怎么会是这样子的?我不敢说出“Unix网络编程”的作者写错了,我也在质疑是否平台环境造成的这种现象,这也是我的疑问,求高手解答
我测试的环境是window 和Linux ................................
其实网上通过wireshark抓包 都是这个样子,但没有找到确切解释(不管怎么说原理是一样的)
将上图简单调整下------window,Linux下的四路握手状态图:
到此结束TCP的三路,四路握手就是这些,下面对上述内容作一简单总结
总结一:
TCP层标识
TCP有个FLAGS字段,这个字段有以下几个常用标识:
SYN(synchronous建立联机)
ACK(acknowledgement 确认)
PSH(push传送)
FIN(finish结束)
RST(reset重置)
URG(urgent紧急)
ACK (Acknowledge number 确认号码)
(但远非这几个,其他的不常用)
总结二:端口状态
TCP 的端口连接状态
1.LISTENING状态 :服务端口启动后处于的状态
2.ESTABLISHED状态:服务端与客户端建立连接成功的状态.表示两台机器可以通信
3.CLOSE_WAIT:对方主动关闭连接或者网络异常导致连接中断,此时我方要调用close来使连接正确关闭
4.TIME_WAIT:调用close方法,并成功收到对方确认后变为TIME_WAIT,测试端口资源不会立即释放
5.SYN_SENT:请求连接时客户端首先要发送同步信号给要访问的机器,此时状态为SYN_SENT,如果连接成功了就变为ESTABLISHED,正常情况下SYN_SENT状态非常短暂
6.SYN_RCVD:当服务器收到客户端发送的同步信号时,将标志位ACK和SYN置1发送给客户端,此时服务器端处于SYN_RCVD状态,如果连接成功了就变为ESTABLISHED,正常情况下SYN_RCVD状态非常短暂