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

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

2、wireshark的使用

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



原文地址:https://www.cnblogs.com/grey-wolf/p/9456645.html

时间: 2024-10-17 11:14:04

wireshark和RawCap跟踪并解决中文乱码问题的相关文章

Cocos2d-x 3.1.1 学习日志4--cocos2d-x解决中文乱码问题的几种办法

做个打飞机的游戏,由于版本太新,网上基本没有教教程,我的版本是cocos2d-x 3.1.1的,今天遇到cocos2dx中中文乱码的问题.无奈只好Google百度寻求答案,明白了这个问题的缘由.因为cocos2d-x内部是以utf8处理文本的,而VS直接输入时文本编码为GBK,如果添加L标志,则为Unicode编码. 解决这个问题有三种办法: 将源代码文件保存为utf8编码,不过由于编译器的问题,这种方式会导致很多无法预测的问题 将字符串用utf8编码集中存到一文件中,然后用代码读取这些字符串来

linux基础-zabbix解决中文乱码问题 (因为版本太新的问题,没有测试成功)

zabbix解决中文乱码问题 1.在windows系统中找一个自己喜欢的字体,这里我们用:msyh.ttf 2.将字体上传至/var/www/html/zabbix/fonts目录下 [[email protected] ~]# cd /var/www/html/zabbix/fonts/ [[email protected] fonts]# rz -yrz waiting to receive.???a? zmodem ′???£ °′ Ctrl+C ???£??′?? msyh.ttf...

解决中文乱码过滤器

解决中文乱码过滤器 import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse;

java解压多目录Zip文件(解决中文乱码问题)--转载

原文地址:http://zhangyongbo.iteye.com/blog/1749439 import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.Enumeration; import org.apache.tools.zi

【原创】通俗易懂地解决中文乱码问题(2) --- 分析解决Mysql插入移动端表情符报错 ‘incorrect string value: '\xF0...

这篇blog重点在解决问题,如果你对字符编码并不是特别了解,建议先看看 < [原创]通俗易懂地解决中文乱码问题(1) --- 跨平台乱码 >. 当然,如果只是针对解决这个Mysql插入报错问题,本篇足够了. 一.定位错误 定位错误绝对是至关重要的一环.我建议遇到问题耐心分析一下比较好,毕竟“不是所有的牛奶都叫特仑苏”. 引起同一个问题的可能有很多,别人的解决方案也许并不适合自己. 那先看看问题出现在哪了,报错如下: 发现的确是编码错误, 16进制的错误提示(\xF0\x9F\x94\xA5\x

javaEE:day2-servlet生命周期、提交解决中文乱码、tomcat加载jar包或类文件的顺序

servlet生命周期 生命周期简介: servlet在服务器第一次被请求的时候new出来,并初始化(即init())再调用service方法.这个实在服务器中new出来,然后用HashMap加的,与客户端无关.客户端之后访问只调用这个servlet的service方法. 具体分为4步: 1 构造方法 :服务器在被客户端第一次请求的时候运行 仅在服务器中运行一次 2 init方法:客户端第一次访问服务器的时候在服务器中进行初始化 仅一次.并且可以通过config参数在 web.xml中通过(ke

HttpServletRequest解决中文乱码的问题

HTTP请求有get和post,这两中方式解决中文乱码的方式如下: 1.Post方式请求 //这句话是设置post请求体的编码为utf-8 request.setCharacterEncoding("utf-8");//获取请求参数 request.getParameter("username"); 2.Get方式请求 new String(request.getParameter("username").getBytes("ISO-8

Android--字符串和16进制相互转化(解决中文乱码)

import java.io.ByteArrayOutputStream; /** * Created by Administrator on 2016/2/2. * -----------16进制和字符串互转--------- * ------------解决中文乱码问题--------- */ public class StringToSixthUtils { private static String hexString = "0123456789abcdef"; /* * 将字

centos7命令行解决中文乱码

参考了一些网上的资料 -----------------版本信息 [[email protected] ~]$ cat /etc/redhat-release  CentOS Linux release 7.0.1406 (Core)  [[email protected] ~]$ uname -m x86_64 [[email protected] ~]$ uname -r 3.10.0-123.el7.x86_64 [[email protected] ~]$ uname -a Linux