Docker下Java文件上传服务三部曲之三:wireshark抓包分析

本文是《Docker下Java文件上传服务三部曲》的终篇,前面两章我们创建了客户端和服务端,实战了文件上传服务,本篇我们通过wireshark工具抓包,分析上传文件时的网络请求;

原文地址:http://blog.csdn.net/boling_cavalry/article/details/79380053

前文简述

《Docker下Java文件上传服务三部曲》旨在实战Docker下的java文件服务的开发和部署,前面两章的地址如下:

  1. 《Docker下Java文件上传服务三部曲之一:准备环境》
  2. 《Docker下Java文件上传服务三部曲之二:服务端开发》

此外还有一篇文章通过阅读源码来学习SpringMVC的文件服务:《SpringMVC源码分析:POST请求中的文件处理》

为何要用wireshar抓包分析?

前面两章已完成了Java文件上传服务的实战,本章不会有新的开发了,为什么还要专门写一篇有关抓包分析的文章呢?
因为我对一个概念很模糊:所谓的“一次POST请求”,“一次”怎么理解?
读者您可能觉得我的问题没描述清楚,其实我也没办法说得更准确了,因为本来就不清楚…


所以还是借助wireshark让POST背后的细节现形吧…

实战环境

如下图,像三部曲的第一章那样用两台电脑进行实战,一台win10作客户端,一台ubuntu作server,win10发起POST请求将文件上传到ubuntu上:
这里写图片描述

ubuntu电脑上的Docker容器是通过以下命令部署的:

docker run --name fileserver001 -p 8080:8080 -idt  bolingcavalry/springbootfileserver:0.0.1-SNAPSHOT

wireshark安装在win10电脑上,抓包分析;

抓包,从简单的开始

我们来试试抓包,一开始先抓个简单的GET请求的,刚才部署的Docker容器提供了一个GET接口,假如ubuntu电脑IP地址是118.24.0.64,在浏览器可以通过这个URL访问:http://118.24.0.64:8080/hello

响应是个字符串,如下图所示:
这里写图片描述

接下来我们就来抓这个请求响应的包:

  1. 打开wireshark应用,选好对应的网卡(例如我是在局域网中,所以选的是WLAN);
  2. 设置过滤规则,假如ubuntu电脑IP地址是118.24.0.64,那么过滤规则就是ip.src == 118.24.0.64 or ip.dst == 118.24.0.64,意思是只展示发往118.24.0.64的数据和118.24.0.64返回的数据,设置方式如下图所示,请按照数字的顺序进行操作:
    这里写图片描述

  3. 为了抓到纯净的数据,请不要再和ubuntu电脑有其他连接,例如SecureCRT等工具如果还有连接请立即关闭,否则按照上述过滤规则也会将ssh协议的数据抓到;

  4. 打开chrome浏览器的隐身窗口,地址栏输入:http://118.24.0.64:8080/hello

  5. wireshark抓到的数据如下图所示:
    这里写图片描述
    如上图所示,我们看到了TCP握手,握手成功后客户端发起GET请求,服务端收到后立即ACK,然后再以HTTP协议向客户端返回数据;
    然后,我们还看到了保持连接的Keep-Alive包,以及关闭连接的FIN包;
    然后,浏览器还在尝试着通过Keep-Alive保持连接;

GET请求的抓包就到这里吧,接下来看看POST请求的抓包;

POST请求抓包

像前两章那样在win10电脑上运行UploadFileClient类,将win10上的文件POST到ubuntu电脑上,抓到了如下图的包:
这里写图片描述

这么多数据包,看来所谓的“一次POST请求”,果然没那么简单…

本次POST的文件大小为150K左右,上图红框中,POST请求的大小才307字节,所以本次上传的文件数据,并不是HTTP协议上传到服务端的,而是通过下图红框中那些备注为“TCP segment of a ressembled PDU”的TCP包上传上去的:

这里写图片描述

"TCP segment of a ressembled PDU"是指TCP层收到上层大块报文后分解成段后发出去,所以150K的文件被拆分成了多个TCP包发送;

此处有个小疑问,如下图,为什么每个TCP包的数据段大小都是1424呢?
这里写图片描述

我们看看最开始TCP握手时的协议,如下图:
这里写图片描述

如上图红框所示,TCP握手的时候,服务端的[SYN, ACK]包中规定了MSS=1424,所以后面的TCP包中数据段都没有超过此大小;

现在终于清楚了,一次POST请求,并不等于一个http协议的数据包,实际上在TCP层会有多个包负责整个数据的传输,并且这些包都会有来自服务端的ACK

至此,《Docker下Java文件上传服务三部曲》就全部结束了,希望此系列能够帮您加深对文件服务的理解,更希望能在实战中帮助到您;

欢迎关注我的公众号:程序员欣宸

在这里插入图片描述

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
使用Docker运行Java应用程序时,可能需要将文件上传到容器的主目录(/home)中。通常可以使用docker cp命令将文件从主机复制到容器中,但在某些情况下,如果需要实现自动化,则需要将该过程包含在脚本或应用程序中。 一个简单的解决方案是使用Java的标准类库中的FileInputStream和FileOutputStream类。假设我们有一个名为file.txt的文件,位于主机中的/home/user/目录下。在Docker容器中,可以使用以下代码将该文件复制到容器中的/home/目录: ```java import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class FileCopy { public static void main(String[] args) { String source = "/home/user/file.txt"; String destination = "/home/file.txt"; try (FileInputStream fis = new FileInputStream(source); FileOutputStream fos = new FileOutputStream(destination);) { byte[] buffer = new byte[1024]; int length; while ((length = fis.read(buffer)) > 0) { fos.write(buffer, 0, length); } } catch (IOException e) { e.printStackTrace(); } } } ``` 通过调用FileInputStream和FileOutputStream类的构造函数,可以将源文件和目标文件的路径传递给它们。然后,在while循环中,逐个字节地将源文件的内容写入目标文件中。 请注意,此解决方案依赖于Java类库而不是Docker命令。因此,它可以在任何支持Java的操作系统上运行,并且可以应用于从其他位置到/home目录的任何文件的复制过程。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员欣宸

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值