zoukankan      html  css  js  c++  java
  • wireshark和RawCap跟踪并解决中文乱码问题

    一、问题概述

    说下程序的架构。

    有个后台管理系统A,在页面修改数据后,会用httpClient发http请求给系统B;

    系统B做了异步机制,收到A发的请求后,将数据封装为Mq消息发给RabbitMq,然后结束该请求;

    然后系统B自己也是消费者,去对应的Rabbitmq拉取消息后,封装一个httpClient通知系统C。

    系统C会将该数据放到Redis里面。

    然后我们发现,Redis里面的value出现了中文乱码问题。

    大概的流程如下:

    我采取的办法是,因为我们的所有系统,都默认是要采用“utf-8”来编码,那么我只要一路跟踪请求的链路,看看到底是在哪一步乱码的,就知道问题所在了。

    我准备利用wireshark和rawcap来跟踪链路。本来不需要RawCap,主要是wireshark无法跟踪localhost链路上的网络请求。(上图,系统A、B、Mq在同一台机器上)

    二、链路跟踪

    2.1 A到B的链路跟踪

    上面提到,A是后台管理系统。下面是其界面。

    注意到,上图中,有一个“中”字。而“中”在utf8中被编码为:

    这边先不讲,怎么利用wireshark和rawcap来抓包。先看我们跟踪的结果:

     经过寻找,我们页面上提交的“11中11236ckl111”就在上图红框标出的地方。

    这有个小技巧,我提交的字符串中,“中”字前后有两个1,主要就是方便寻找。

    上图,红框前后各有两个31,(对应数字1),那中间的“e4 b8 ad”就是中字的编码。

    可以看到,这个编码没问题,因为和我们查到的“中”的utf8编码是一致的。

    2.2 B到Mq的链路跟踪

     注意上图,就是系统B发到Mq的消息(上图中红框标识了其协议为AMQP,后面的Basic Publish表示这是一条生产者发送的消息)。

    这里的编码也是没问题的。

    2.3 系统B消费Mq的消息的链路跟踪

     和上一节类似,该消息就是系统B作为消费者从Mq拉到的。

    这里的编码也没问题。

    2.4 系统B消费消息后,发送给系统C的消息的链路跟踪

     注意了,上图这里,我们发现,这次“中”所在的编码,不再是utf-8,而是变成了什么“e6 b6 93 ef bf bd”之类的内容。

    我猜想了半天,实在难以理解为什么编码会变成这样。哪怕utf32也不会用6字节来编码这么一个简单的汉子吧。

    出问题的节点是找到了,那么剩下的就是查看代码。

    2.5 代码问题定位

    上图,第一个红框的位置,是获取消息体的字节数组;

    第二个位置,就是将字节数组解码为String。

    我猜测就是第二步出了问题。

    让我们看看该方法的说明:

     这里是说,将会按照系统的默认字符集来解码。

    我在192.168.19.88上写了个java测试类,打印了下列变量:

    String csn = Charset.defaultCharset().name();


    而结果显示出来就是:

    所以,问题很明显,就是因为本来是utf8的字节,用gbk来解码,当然会乱码。

    2.6 解决办法1

    参考了:

    https://blog.csdn.net/qq_21033663/article/details/53022797

    1、通过System.out.println(System.getProperty("file.encoding"));可查看JVM运行时所使用的编码

    2、默认情况:

    1)Windows下,file.encoding=”GBK”, 
    2)Linux下,file.encoding=”UTF-8”。

    3、通过修改Tomcat配置来指定JVM运行时所使用的编码

    1)linux下,在catalina.sh配置:JAVA_OPTS="$JAVA_OPTS -Dfile.encoding=utf-8"

    2)Windows下:在catalina.bat配置:set JAVA_OPTS=%JAVA_OPTS% -Dfile.encoding=UTF-8

    2.7 解决办法2

    new String的时候,指定正确的解码字符集就可以了。

    如下:

     三、参考资料

    1、RawCap的使用

    https://blog.csdn.net/lz_obj/article/details/53116432

    这个可以多开,同时跟踪多个网卡。

    这里注意的一点是:

    比如两个服务部署在同一个服务器上,但是调用的时候,host用的是真实ip(192.168.19.88)而不是127.0.0.1的话,

    抓包的时候,可以像下面这样:

    RawCap.exe 192.168.19.88 dumpfile.pcap

    2、wireshark的使用

    https://www.cnblogs.com/yuhuameng/p/5871443.html

    3、utf-8编码转换

    http://www.mytju.com/classcode/tools/encode_utf8.asp

    
    
  • 相关阅读:
    使用jmeter进行api接口压力测试
    MAC OS环境下搭建基于Python语言的appium自动化测试环境
    jmeter+python可以用jython来实现
    navicat12.0.27 Mac版破解方法
    uiautomatorviewer连接机器点击报错Unexpected error while obtaining UI hierarchy
    appium+python,终端键值表
    自动化测试--Appium简单的测试demo
    appium+python搭建自动化测试框架_TestAPP框架(三)
    深入理解Java虚拟机-----第二章
    ViewModel组件
  • 原文地址:https://www.cnblogs.com/grey-wolf/p/9456645.html
Copyright © 2011-2022 走看看