php - 为什么我在 web 中观察到的 tcp 连接终止与给定序列图的标准终止不同?

标签 php http tcp

下面来创建tcp连接建立、http请求和响应以及tcp连接终止的全过程。

  1. 我的文件内容:

/var/www/html/phplearn/send.php

<form action="http://127.0.0.1/phplearn/do.php" method="post">
name: <input type="text" name="userName" size="12"/>
key:  <input type="text" name="PS" size="12"/>
<input type="submit" value="login">
</form>

/var/www/html/phplearn/do.php

<?php
$userName = $_POST["userName"];
$PS = $_POST["PS"];
echo "the name is:  ".$userName;
echo "<br>key word is:  ".$PS;
?>
  1. 使用此参数打开 tcpdump:

    sudo tcpdump -i lo host 127.0.0.1 -w/tmp/dataDst.pcap

  2. 使用 curl 发送信息

    curl -d "userName=test&PS=test_pass"127.0.0.1/phplearn/do.php

  3. 用 wireshark 打开/tmp/dataDst.pcap

enter image description here

进程1:tcp连接建立。

enter image description here

从 no1 到 no3,没问题。

Process2:http请求和响应。
no5 客户端从 38219 端口向服务器的 80 端口发送 http 请求
no6 服务器向客户端发送 tcp 信号
no7 服务器向客户端发送 http 响应

进程3:tcp连接终止
从tcpdump中观察到的tcp连接终止过程与网上的图完全不同。

enter image description here

据我观察,
no7 从客户端在端口 38219 到服务器端口 80 ACK
no8 从端口 38219 上的客户端到服务器端口 80 FIN
no9 从服务器端口 80 到客户端端口 38219 FIN
no10 从客户端在端口 38219 到服务器端口 80 ACK

从图中可以看出,从客户端到服务器有两个tcp包,从服务器到客户端有两个tcp包。

从我的 tcpdump 中,从客户端到服务器有 3 个 tcp 数据包,从服务器到客户端只有一个 tcp 数据包。

你能详细解释一下我的观察结果和时序图不一样的原因吗?

最佳答案

  • 数据包 7 中,客户端确认收到 HTTP 来自服务器的响应 OK 数据包。这不属于您的 TCP-连接-关闭序列图中,因为它不属于它,而是属于正常的 TCP 传输。

  • 然后客户端在packet 8中表示它想要关闭 联系。请注意,尽管此数据包中设置了 ACK-flag,但它不会确认收到任何新数据,因为 ACK-number 的值是相同的(194)。检查数据包 7。ACK 的值也是 194。此步骤对应于图表的第一个箭头。

  • packet 9中服务器确认关闭指示 客户并告诉客户,它也想终止他的一方 的连接。此步骤对应于图表中从服务器到客户端的两个箭头。您的服务器将其打包在一个数据包中,与发送两个数据包相比,这很聪明,因为它可以节省数据。

  • 数据包 10 中,客户端确认,服务器也想要 终止他的连接部分并且连接是 因此关闭双方。此步骤对应于图表的最后一个箭头。

这完全遵循您在问题中嵌入的序列图,但是 ACK 数据包与 FIN 数据包一起发送

请注意,TCP 是双向的,因此客户端可以向服务器发送消息,而服务器可以通过相同的连接对此做出响应。但它也允许半关闭连接。这意味着,尽管客户端在数据包 8 中表示他不想再发送,但他仍然可以从服务器接收数据。 但是由于服务器不想再发送数据,他还通过数据包 9 中的 FIN 数据包表明了这一点。我告诉你这个你可能想知道,为什么服务器还需要向客户端发送 FIN 数据包。

TCP State Model

有关 TCP 连接状态模型的有用且更详细的图形可以在 Tanenbaum p. 中找到。 532 或者它也被描述在此 lecture slides苏黎世联邦理工学院。

关于php - 为什么我在 web 中观察到的 tcp 连接终止与给定序列图的标准终止不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44944444/

相关文章:

php - 在执行函数之前检查sql中的日期时间

node.js - 使用Nodejs发出POST请求时,如何获取请求负载的内容长度?

javascript - 如何在 AngularJS 中访问请求的 HTTP header

c# - 为什么我不能使用 TCP 客户端发送两个消息? (续)

php - 使用 coma(,) 通过复选框 php my sl 从表中过滤条目

java - 获取Word文档数和PPT中幻灯片数

http - 同时使用 "Expires: 0"、 "no-cache"、 "no-store"、 "max-age=0, must-revalidate"- 有什么用?

networking - ARP报文中的源MAC地址和封装时指定的源MAC地址有什么区别?

tcp - 银行 atm tcp 消息负载平衡和路由使用 java nio/netty 和 activemq

java - Google 应用引擎上的 JSON 输出