TCP/IP协议族的传输层基础(3)——TCP协议的三次握手与四次挥手

TCP连接的建立和关闭

我们先通过tcpdump来抓取一个建立连接的TCP报文,假设我们有两台机器,在一台机器上通过telnet应用程序远程登录另一台的telnet客户端,查看之间交换的TCP报文。

执行下面的命令
sudo tcpdump -nt -i eth0 '(src 192.168.224.136 and dst 192.168.224.138) or (src 192.168.224.138 and dst 192.168.224.136)'

telnet 192.168.224.138 //我们在192.168.224.138这台机器上开启了telnet服务,在192.168.224.136这台机器上去远程登录138的机器

之后按下ctrl+]进入telnet命令行,输入quit关闭连接

抓包的结果如下(将重要的部分要红色字体标了出来,即三次握手和四次挥手)
//建立连接之前,进行三次握手
1.IP 192.168.224.136.42746 > 192.168.224.138.telnet: Flags [S], seq 4100382577, win 29200, options [mss 1460,sackOK,TS val 2175295 ecr 0,nop,wscale 7], length 0

2.IP 192.168.224.138.telnet > 192.168.224.136.42746: Flags [S.], seq 3413452905, ack 4100382578, win 14480, options [mss 1460,sackOK,TS val 2193678 ecr 2175295,nop,wscale 6], length 0

3.IP 192.168.224.136.42746 > 192.168.224.138.telnet: Flags [.], ack 1, win 229, options [nop,nop,TS val 2175295 ecr 2193678], length 0

//关闭连接之后,进行四次挥手(注意这里实际只有三个报文)
4.IP 192.168.224.136.42746 > 192.168.224.138.telnet: Flags [F.], seq 77, ack 128, win 229, options [nop,nop,TS val 2184361 ecr 2193810], length 0

5.IP 192.168.224.138.telnet > 192.168.224.136.42746: Flags [F.], seq 128, ack 78, win 227, options [nop,nop,TS val 2229952 ecr 2184361], length 0

6.IP 192.168.224.136.42746 > 192.168.224.138.telnet: Flags [.], ack 129, win 229, options [nop,nop,TS val 2184361 ecr 2229952], length 0
三次握手建立连接
  • 第一个报文包含SYN标志(Flags[S]),是一个同步报文段,136的主机向138的主机发起连接请求,同时该报文段含有一个ISN值为4100382577的序号(系统随机生成)
  • 第二个报文也是同步报文段,表示138的主机同意与136的主机建立连接,同时它发送自己的ISN值为3413452905的序号,并对第一个同步报文段进行确认。确认值是4100382578,即第一个同步报文段的序号值+1。同步报文段比较特殊,即使它没有携带任何应用程序数据,它也要占用一个序号值(这里我们的连接并没有发送任何数据)
  • 第三个报文段是对第二个报文段的确认。至此连接建立完成

四次挥手断开连接(注意这里实际上我们只有三个报文,这里有一个捎带应答的过程,后续会讲到)
  • 第四个报文段包含FIN标志(Flags[F]),是一个结束报文段,136的主机向138的主机发起断开连接请求,同时该报文段含有一个ISN值为77的序号
  • 第五个报文段注意了,这里有了一个捎带应答的机制,即本来136的主机应该先发送一个ACK确认报文,再发送一个自己的结束报文段(如下面的图),它带有一个序号128,但是这里结束报文段中捎带了一个ACK确认报文,形成了捎带应答,可以看到它有一个ack 78,这是对上一个报文段的请求的确认,是上面的序号+1。本来其实应该还要发一个类似下面的报文,这里就不发了,直接捎带了
IP 192.168.224.138.telnet > 192.168.224.136.42746: Flags [.], ack 78, win 227, options [nop,nop,TS val 2229952 ecr 2184361], length 0
  • 第六个报文段就是136主机对138主机发来的结束报文段的确认,ack是129,是上一个报文段的序号+1
关于三次握手和四次挥手的问题,用下图具体来看
TCP/IP协议族的传输层基础(3)——TCP协议的三次握手与四次挥手

注意:服务器和客户端应用程序判断对方是否已经关闭连接的方法是read系统调用返回0!!!(这意味着收到了结束报文段)

关于上图的这些客户端与服务器的状态,在下一篇文章再来叙述。