通过Wireshark抓包详解HTTP,TCP/IP工作流程

前言

这篇文章通过现实生活形象比喻,解释各种专业术语与网络模型;在Tomcat服务器的逻辑代码中实际代码断点,结合Wireshark网络抓包,充分直观的了解HTTP,TCP/IP协议工作流程;读完这篇文章,希望你能够:

    对于计算机网络有初步的认识和了解,了解一些经典专业术语,如 MTU,三次握手、四次挥手。 对TCP/IP有比较直观的理解,面试再问到的时候,可以从容不迫的解答。 Http请求报文与响应报文封装格式,数据包在网络中如何进行传输。

HTTP、TCP/IP工作流程

    TCP/IP通俗比喻:IP是路(公路+国道+高速),TCP是客车,Http是乘客(乘客有多种:Http乘客,MAIL乘客,FTP乘客,DNS乘客......) TCP三次握手可以理解为发短信:例如要从杭州到北京,TCP客车发车前,需要确认杭州到北京道路是否畅通,杭州站发短信给北京站进行确认。 杭州站发短信给北京站,我有客车要来北京 北京站收到短信,发送一条短信给杭州站,好的,路是通的过来吧 杭州站收到短信,再发送一条短信给北京站,收到,我马上发车过来了! 下面进行实际演练,代码断点,Wireshark抓包

1.tomcat启动,代码断点在处理IO流之前,这样能清楚的看到3次握手的数据包。

2.在tomcat服务器返回报文处理进行断点,先中止发送响应数据包,直接抓request报文请求的数据包。

3.继续跟踪tomcat服务器上个断点代码response.finishResponse(),会调用sendHeaders()方法,把响应报文请求头发送到客户端,发送数据包到网络的触发动作是调用outputWrieter.flush()。这时候就可以抓到数据包了。

try {
                    response.finishResponse();
                } catch (IOException e) {
                    ok = false;
                } catch (Throwable e) {
                    log("process.invoke", e);
                    ok = false;
                }
// Flush the headers and finish this response
        sendHeaders();
        super.finishResponse();
// Send a terminating blank line to mark the end of the headers
        outputWriter.print("
");
        //输出流,把请求头响应数据,缓冲到系统内核,系统内核发送给网卡,发送到网络中
        outputWriter.flush();
        // System.out.println("----------");

        // The response is now committed
        committed = true;

4.发送完响应头数据,tomcat会再发送响应体数据(就是servlet里service方法或springMvc 具体controller业务逻辑代码处理完成,返回的数据结果)."from service"

@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        String name=req.getParameter("name");
        System.out.println(name);
        res.getWriter().println("from service");
        System.out.println("from service");
    }

5.业务数据包发送完后,tomcat需要再发送一个结束标识的数据包"0/r/n/r/n",告之客户端HttpResponse响应报文数据传送完成,并关闭输出流.

if (useChunking) {
            // Write the final chunk.
            writingChunk = true;
            try {
                print("0

");
            } finally {
                writingChunk = false;
            }
        }

6.最后观察一下,一个完整的Http连接请求报文与响应报文封装格式

经验分享 程序员 微信小程序 职场和发展