从TCP层面分析POST请求

1.问题的提出

前段时间参加一个公司的面试,面试官提出一个问题:请从底层的角度分析HTTP协议中的POST和GET的区别。

当时我没能回答这个问题,后面问面试官这个问题,结果他也没有答出来。自己回来的路上一路思考并且搜索了相关的资料,网上的说法是:POST是分成两个TCP发出去,一个是Header头部分的TCP包,一个是Body的TCP包。自己心里面怀疑这个答案是否正确,因为如果按照网上的说法来进行系统设计的话,存在一定的性能问题,因为只包含header的TCP包的话肯定比较小,这个TCP包本来可以装更多的内容的,所以对网络的性能存在一定的浪费。

基于上述的怀疑,自己决定使用wireshark对POST方式的HTTP请求进行抓包,因此有了这一篇文章。

2.客户端和服务器端的代码

2.1 客户端的POST请求代码

写了一个简单的form页面,代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="http://52.198.228.221/post.php" method="post" enctype="multipart/form-data">
    <input name="test" type="text">
    <button type="submit">确定</button>

</form>
</body>
</html>

2.2 采用Postman作为客户端

分别将postman作为独立软件和chrome插件两者方式进行测试。

2.3 服务器端的代码

服务器端的代码很简单,直接把post提交的内容显示出来即可,代码如下:

<?php
    var_dump($_POST);

3.测试结果

3.1 使用Chrome的原生form页面提交

3.1.1 大批量内容发送

我们使用大量的文字进行发送,使用的浏览器是chrome 63: 输入图片说明

我们可以看到,这次TCP请求是分成4个tcp segment进行发送。我们再查看一下第一个TCP包:

输入图片说明

从tcp的内容可以看到,该数据表只包含HTTP的Header部分,不包含Body的内容。

3.1.2 少量内容发送

我们接下来使用少量的文字进行发送,Chrome可以一次性的发送所有内容到服务器:

输入图片说明

我们可以到Chrome没有进行TCP分包发送,一个TCP包就发送了所有的内容。

3.2 使用Firefox的原生form页面提交

3.2.1 大批量内容发送

我们使用大量的文字进行发送,使用的浏览器是Firefox 57:

输入图片说明

我们可以看到,在发送同样的大批量内容的情况下,Firefox是分成了3个tcp segment发送,我们查看一下第一个TCP包:

输入图片说明

我们看到,Firefox的第一个TCP已经不仅包含了HTTP中的Header的内容,而且包含了部分Body的内容。

3.2.2 少量内容发送

我们接下来使用少量的文字进行发送:

输入图片说明

Firefox的结果和Chrome一样,都是一个TCP包把内容发完。

3.3 使用Postman(浏览器插件模式)进行POST提交

3.3.1 大批量内容发送

因为Postman是以浏览器插件的形式运行的,所以结果基本和上面Chrome的结果一样:

输入图片说明

Postman发送的第一个TCP包:

输入图片说明

和Chrome的结果一样,第一个TCP包只有HTTP中Header的内容。

3.3.2 少量内容发送

与Chrome的结果一样,一个TCP包把全部内容发完:

输入图片说明

3.4 使用Postman(独立软件模式)进行POST提交

由于在Postman的官网上,出现了新版的Postman,它作为一个独立的软件出现,不再是一个Chrome的插件,我们同样对其进行了测试:

3.4.1 大批量内容发送

输入图片说明

我们可以看到它和作为Chrome插件的Postman在TCP包的分割上有不同,发送同样的内容,这里是分割成为3个TCP Segments的,而插件版的Postman是分割成4个TCP Segments的。

我们在看看第一个TCP包的情况:

输入图片说明

第一个TCP包已经包含有HTTP协议中Body的部分内容。

3.4.2 少量内容发送

和其他测试的结果一样,一个TCP包把全部内容发完:

输入图片说明

3.5 使用PHPStorm自带的rest测试工具进行POST提交(底层是Apache HttpClient 4.5.2)

具体的设置如下:

输入图片说明

3.5.1 大批量内容发送

输入图片说明

我们可以看到是分成了3个TCP Segments进行发送的,我们再看一下第一个TCP包的内容:

输入图片说明

可以看到,第一个TCP不仅有HTTP的Header的内容,还带有部分Body的内容。

3.5.2 少量内容发送

输入图片说明

和其他的客户端一样,都是一个TCP包发完。

4.总结

上面进行了5个客户端的抓包测试,我们把结果总结成以下的表格:

客户端大批量内容发送分成的TCP Segments数量第一个TCP的内容少量内容发送的TCP Segments数量
Chrome634Header1
Firefox573Header+Body1
Postman(浏览器插件模式)4Header1
Postman(独立软件模式)3Header+Body1
PHPStorm(底层是Apache HttpClient)3Header+Body1

通过上述的测试,我们发现文章开头提到的“POST是分成两个TCP发出去,一个是Header头部分的TCP包,一个是Body的TCP包”是错误的,在一个TCP包能所有内容发完的情况下,只发一个TCP包,不会把HTTP的Header和Body的内容分成两个TCP包。

转载于:https://my.oschina.net/cloes/blog/1604256

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值