- 浏览: 253974 次
- 性别:
- 来自: 南京
文章分类
最新评论
-
lixia0417:
如果代理是使用命令行选项启动的,那么代理类还有一个要使用的 a ...
BTrace系列之五:实现原理 -
java_cache:
不错,讲得挺详细,果断收藏
Eclipse Debug不为人知的秘密 -
zhupeijun23:
有点懂了
HttpClient重定向 -
tss0823:
非常好的文章!
BTrace实际案例分析 -
763863446:
好好好,尽量不要用debug.
Eclipse Debug不为人知的秘密
通过TCP码流识别编码
前几天和北京的MM在联调时候出现一个问题,下面就简述下整个问题的定位过程,其中有很多思想还是对定位问题很有帮助的。
问题是这样的,我们是服务器,而MM那边是使用客户端手机进行交互,而双方约定好使用utf-8来编解码。但是在联调过程中,在解析中文时出现了乱码(?)所以经过初步判断可以认定是MM那边上送了GBK编码的中文,而服务端这边使用了UTF-8编码来解码,那自然出现乱码?(注意GBK编码的中文,使用UTF-8来解码时,通常会出现?,通过这个表面现象也可以初步判断一定问题)。而客户端的MM非常肯定的说上送的UTF-8编码的中文。完全有一种不到黄河心不死的感觉!没办法,看来得使用一些手段让MM屈服,让他现出原型。
问题定位过程:我们知道数据是通过二进制流在网络中传输的,所以可以将码流通过抓包的方式抓到,然后tcpdump命令可以帮我们完成这个任务。
使用命令tcpdump -i eth0 tcp port <端口> -Xs 10000 -vv,抓到数据报如下
14:51:21.122716 IP (tos 0x0, ttl 51, id 25274, offset 0, flags [DF], length: 301) 221.130.33.135.23966 > pim2.pim.28080: P [tcp sum ok] 788:1037(249) ack 1 win 33516 <nop,nop,timestamp 1943931360 3385024464>
0x0000 4500 012d 62ba 4000 3306 3b3e dd82 2187 E..-b.@.3.;>..!.
0x0010 c0a8 e920 5d9e 6db0 c90d 5138 eadd b169 ....].m...Q8...i
0x0020 8018 82ec 86a2 0000 0101 080a 73de 09e0 ............s...
0x0030 c9c3 5fd0 789c a551 416a c330 10bc 17fa .._.x..QAj.0....
0x0040 87e0 7b2b ed4a b215 5014 2826 e043 2f76 ..{+.J..P.(&.C/v
0x0050 fa00 9388 6088 e5b6 2ac1 e9eb bb9b 38b8 ....`...*.....8.
0x0060 507a 28bd 6867 6747 338b e4d6 637f 5c9c Pz(.hggG3...c.\.
0x0070 c27b ea86 b8ca e051 668b 1077 c3be 8b87 .{.....Qf..w....
0x0080 55f6 b2dd 3cd8 6ced efef 5c19 cbf6 a3ad U...<.l...\.....
0x0090 c31b 37cf e950 951e 9cb8 0266 da91 70d3 ..7..P.....f..p.
0x00a0 7d06 8f52 5b9a cc04 df0e 27d2 2953 60ae }..R[.....'.)S`.
0x00b0 246a 6509 2d25 3a71 1db0 82dc b7e7 d7e0 $je.-%:q........
0x00c0 539f 88be 7534 791a 462e 9796 226f 74d3 S...u4y.F..."ot.
0x00d0 272e d59e 493a 5942 d920 25a0 82c2 2865 '...I:YB..%...(e
0x00e0 487c 517a 90b9 b100 da89 8689 da83 b245 H|Qz...........E
0x00f0 5e58 ad73 5ab5 664e 4c7e b32d feb0 5d02 ^X.sZ.fNL~.-..].
0x0100 d2f2 38db a241 2931 0765 0c82 253f f853 ..8..A)1.e..%?.S
0x0110 82fa 2541 ff33 a14a 9b2e b647 7f26 ff09 ..%A.3.J...G.&..
0x0120 f274 7a48 f1fd 2bbf 00db f77f 43 .tzH..+.....C
由于tcpdump抓到数据是IP数据报格式,所以必须理解IP数据报和TCP段格式才可以将里边真正的数据截取出来。IP数据报的长度是由第一个字节的低4位表示,也就是报文中的
0x0000 4500 012d 62ba 4000 3306 3b3e dd82 2187 E..-b.@.3.;>..!.,红色部分,由于IP数据报和TCP段格式都是以段为单位一个段是4字节,所以4 * 5表示IP数据报的长度是20字节,所以将IP数据报的数据去掉只剩下如下报文。、
5d9e 6db0 c90d 5138 eadd b169 ....].m...Q8...i
0x0020 8018 82ec 86a2 0000 0101 080a 73de 09e0 ............s...
0x0030 c9c3 5fd0 789c a551 416a c330 10bc 17fa .._.x..QAj.0....
0x0040 87e0 7b2b ed4a b215 5014 2826 e043 2f76 ..{+.J..P.(&.C/v
0x0050 fa00 9388 6088 e5b6 2ac1 e9eb bb9b 38b8 ....`...*.....8.
0x0060 507a 28bd 6867 6747 338b e4d6 637f 5c9c Pz(.hggG3...c.\.
0x0070 c27b ea86 b8ca e051 668b 1077 c3be 8b87 .{.....Qf..w....
0x0080 55f6 b2dd 3cd8 6ced efef 5c19 cbf6 a3ad U...<.l...\.....
0x0090 c31b 37cf e950 951e 9cb8 0266 da91 70d3 ..7..P.....f..p.
0x00a0 7d06 8f52 5b9a cc04 df0e 27d2 2953 60ae }..R[.....'.)S`.
0x00b0 246a 6509 2d25 3a71 1db0 82dc b7e7 d7e0 $je.-%:q........
0x00c0 539f 88be 7534 791a 462e 9796 226f 74d3 S...u4y.F..."ot.
0x00d0 272e d59e 493a 5942 d920 25a0 82c2 2865 '...I:YB..%...(e
0x00e0 487c 517a 90b9 b100 da89 8689 da83 b245 H|Qz...........E
0x00f0 5e58 ad73 5ab5 664e 4c7e b32d feb0 5d02 ^X.sZ.fNL~.-..].
0x0100 d2f2 38db a241 2931 0765 0c82 253f f853 ..8..A)1.e..%?.S
0x0110 82fa 2541 ff33 a14a 9b2e b647 7f26 ff09 ..%A.3.J...G.&..
0x0120 f274 7a48 f1fd 2bbf 00db f77f 43 .tzH..+.....C
剩下的报文有TCP段格式和真正的数据体构成,而TCP段格式的第13个字节的高4位代表整个TCP段格式的首部长度,也就是如下报文中的红色部分
5d9e 6db0 c90d 5138 eadd b169 ....].m...Q8...i
0x0020 8018 82ec 86a2 0000 0101 080a 73de 09e0 ............s...
4 * 8=32,也就是TCP段格式的首部长度为32字节。
截取TCP段格式的数据剩下如下所示:
789c a551 416a c330 10bc 17fa .._.x..QAj.0....
0x0040 87e0 7b2b ed4a b215 5014 2826 e043 2f76 ..{+.J..P.(&.C/v
0x0050 fa00 9388 6088 e5b6 2ac1 e9eb bb9b 38b8 ....`...*.....8.
0x0060 507a 28bd 6867 6747 338b e4d6 637f 5c9c Pz(.hggG3...c.\.
0x0070 c27b ea86 b8ca e051 668b 1077 c3be 8b87 .{.....Qf..w....
0x0080 55f6 b2dd 3cd8 6ced efef 5c19 cbf6 a3ad U...<.l...\.....
0x0090 c31b 37cf e950 951e 9cb8 0266 da91 70d3 ..7..P.....f..p.
0x00a0 7d06 8f52 5b9a cc04 df0e 27d2 2953 60ae }..R[.....'.)S`.
0x00b0 246a 6509 2d25 3a71 1db0 82dc b7e7 d7e0 $je.-%:q........
0x00c0 539f 88be 7534 791a 462e 9796 226f 74d3 S...u4y.F..."ot.
0x00d0 272e d59e 493a 5942 d920 25a0 82c2 2865 '...I:YB..%...(e
0x00e0 487c 517a 90b9 b100 da89 8689 da83 b245 H|Qz...........E
0x00f0 5e58 ad73 5ab5 664e 4c7e b32d feb0 5d02 ^X.sZ.fNL~.-..].
0x0100 d2f2 38db a241 2931 0765 0c82 253f f853 ..8..A)1.e..%?.S
0x0110 82fa 2541 ff33 a14a 9b2e b647 7f26 ff09 ..%A.3.J...G.&..
0x0120 f274 7a48 f1fd 2bbf 00db f77f 43 .tzH..+.....C
这个就是我们真正的从客户端上送的数据,所以将他拿到后,由于是16进制的所以需要将这些数据转成byte数据,就可以使用他new String(b, "UTF-8"),来检验客户端上送的报文是否是UTF-8编码的,如果显示乱码那么就应该不是UTF-8编码的。
byte[] bb = new byte[]{(byte)0x78,(byte)0x9c,(byte)0xa5,(byte)0x51,(byte)0x41(byte)0x6a,(byte)0xc3,(byte)0x30,(byte)0x10,(byte)0xbc,(byte)0x17,(byte)0xfa,
(byte)0x87,(byte)0xe0,(byte)0x7b,(byte)0x2b,(byte)0xed(byte)0x4a,(byte)0xb2,(byte)0x15,(byte)0x50,(byte)0x14,(byte)0x28,(byte)0x26,(byte)0xe0,(byte)0x43,(byte)0x2f,(byte)0x76,
(byte)0xfa,(byte)0x00,(byte)0x93,(byte)0x88,(byte)0x60(byte)0x88,(byte)0xe5,(byte)0xb6,(byte)0x2a,(byte)0xc1,(byte)0xe9,(byte)0xeb,(byte)0xbb,(byte)0x9b,(byte)0x38,(byte)0xb8,
(byte)0x50,(byte)0x7a,(byte)0x28,(byte)0xbd,(byte)0x68(byte)0x67,(byte)0x67,(byte)0x47,(byte)0x33,(byte)0x8b,(byte)0xe4,(byte)0xd6,(byte)0x63,(byte)0x7f,(byte)0x5c,(byte)0x9c,
(byte)0xc2,(byte)0x7b,(byte)0xea,(byte)0x86,(byte)0xb8(byte)0xca,(byte)0xe0,(byte)0x51,(byte)0x66,(byte)0x8b,(byte)0x10,(byte)0x77,(byte)0xc3,(byte)0xbe,(byte)0x8b,(byte)0x87,
(byte)0x55,(byte)0xf6,(byte)0xb2,(byte)0xdd,(byte)0x3c(byte)0xd8,(byte)0x6c,(byte)0xed,(byte)0xef,(byte)0xef,(byte)0x5c,(byte)0x19,(byte)0xcb,(byte)0xf6,(byte)0xa3,(byte)0xad,
(byte)0xc3,(byte)0x1b,(byte)0x37,(byte)0xcf,(byte)0xe9(byte)0x50,(byte)0x95,(byte)0x1e,(byte)0x9c,(byte)0xb8,(byte)0x02,(byte)0x66,(byte)0xda,(byte)0x91,(byte)0x70,(byte)0xd3,
(byte)0x7d,(byte)0x06,(byte)0x8f,(byte)0x52,(byte)0x5b(byte)0x9a,(byte)0xcc,(byte)0x04,(byte)0xdf,(byte)0x0e,(byte)0x27,(byte)0xd2,(byte)0x29,(byte)0x53,(byte)0x60,(byte)0xae,
(byte)0x24,(byte)0x6a,(byte)0x65,(byte)0x09,(byte)0x2d(byte)0x25,(byte)0x3a,(byte)0x71,(byte)0x1d,(byte)0xb0,(byte)0x82,(byte)0xdc,(byte)0xb7,(byte)0xe7,(byte)0xd7,(byte)0xe0,
(byte)0x53,(byte)0x9f,(byte)0x88,(byte)0xbe,(byte)0x75(byte)0x34,(byte)0x79,(byte)0x1a,(byte)0x46,(byte)0x2e,(byte)0x97,(byte)0x96,(byte)0x22,(byte)0x6f,(byte)0x74,(byte)0xd3,
(byte)0x27,(byte)0x2e,(byte)0xd5,(byte)0x9e,(byte)0x49(byte)0x3a,(byte)0x59,(byte)0x42,(byte)0xd9,(byte)0x20,(byte)0x25,(byte)0xa0,(byte)0x82,(byte)0xc2,(byte)0x28,(byte)0x65,
(byte)0x48,(byte)0x7c,(byte)0x51,(byte)0x7a,(byte)0x90(byte)0xb9,(byte)0xb1,(byte)0x00,(byte)0xda,(byte)0x89,(byte)0x86,(byte)0x89,(byte)0xda,(byte)0x83,(byte)0xb2,(byte)0x45,
(byte)0x5e,(byte)0x58,(byte)0xad,(byte)0x73,(byte)0x5a(byte)0xb5,(byte)0x66,(byte)0x4e,(byte)0x4c,(byte)0x7e,(byte)0xb3,(byte)0x2d,(byte)0xfe,(byte)0xb0,(byte)0x5d,(byte)0x02,
(byte)0xd2,(byte)0xf2,(byte)0x38,(byte)0xdb,(byte)0xa2(byte)0x41,(byte)0x29,(byte)0x31,(byte)0x07,(byte)0x65,(byte)0x0c,(byte)0x82,(byte)0x25,(byte)0x3f,(byte)0xf8,(byte)0x53,
(byte)0x82,(byte)0xfa,(byte)0x25,(byte)0x41,(byte)0xff(byte)0x33,(byte)0xa1,(byte)0x4a,(byte)0x9b,(byte)0x2e,(byte)0xb6,(byte)0x47,(byte)0x7f,(byte)0x26,(byte)0xff,(byte)0x09,
(byte)0xf2,(byte)0x74,(byte)0x7a,(byte)0x48,(byte)0xf1(byte)0xfd,(byte)0x2b,(byte)0xbf,(byte)0x00,(byte)0xdb,(byte)0xf7,(byte)0x7f,(byte)0x43};
//该码流是被压缩过的所以要先解压
byte[] aa = GzipUtility.unzip(bb);
try
{
System.out.println(new String(aa, "UTF-8"));
}
catch (UnsupportedEncodingException e)
{
e.printStackTrace();
}
输出结果:
<?xml version="1.0" encoding="UTF-8"?>
<DnDataReq>
<MsgID>1</MsgID>
<MaxMsgSize>2048</MaxMsgSize>
<DevID>35726302438572902</DevID>
<DataType>sms</DataType>
<Box>
<Type>1</Type>
<Sms>
<Id>1</Id>
<T>20100123175335</T>
<S>10658114</S>
<R>????</R>
</Sms>
<Sms>
<Id>2</Id>
<T>20100129120242</T>
<S>1252002613552187841</S>
<R>????</R>
</Sms>
<Sms>
<Id>3</Id>
<T>20100129120244</T>
<S>1252002613552187841</S>
<R>????</R>
</Sms>
<IsFinal>y</IsFinal>
</Box>
</DnDataReq>
而用GBK解码后,输出结果:
<?xml version="1.0" encoding="UTF-8"?>
<DnDataReq>
<MsgID>1</MsgID>
<MaxMsgSize>2048</MaxMsgSize>
<DevID>35726302438572902</DevID>
<DataType>sms</DataType>
<Box>
<Type>1</Type>
<Sms>
<Id>1</Id>
<T>20100123175335</T>
<S>10658114</S>
<R>内容</R>
</Sms>
<Sms>
<Id>2</Id>
<T>20100129120242</T>
<S>1252002613552187841</S>
<R>内容</R>
</Sms>
<Sms>
<Id>3</Id>
<T>20100129120244</T>
<S>1252002613552187841</S>
<R>内容</R>
</Sms>
<IsFinal>y</IsFinal>
</Box>
</DnDataReq>
MM终于在铁的事实面前屈服了。
发表评论
-
BTrace实际案例分析
2012-02-17 17:24 6426BTrace实际案例分析 问题表象 问题描述 ... -
BTrace工具实例应用
2012-02-17 17:18 3966BTrace工具使用简介 “Hello World” ... -
BTrace工具简介
2012-02-17 17:09 12517BTrace工具简介 What is Btrace? ... -
使用JDI调试多线程程序
2012-02-09 11:17 0前几天写了一篇Eclipse的debug技巧,引来不少童鞋的口 ... -
Eclipse Debug不为人知的秘密
2012-02-07 15:54 39204Debug视图 认识debug视图,红色部分框为线程堆栈视 ... -
PIM系统架构浅析
2010-06-20 15:43 2211PIM系统架构浅析 我们真的需要分 ... -
日志打印
2010-06-20 15:26 1756日志打印 ü 日志重要性 ü ... -
JSON简介
2010-06-20 15:22 2532JSON简介 ü JSON简介及其应用场景 ... -
Java编程中汉字问题的初探
2010-06-20 15:09 12531. 前言 在基于Java语言 ... -
接口模块的定义
2010-06-20 14:35 1200接口模块的定义 1 作为接口模块,必须要在设计时仔细逐 ... -
JDBC当中的批处理
2010-06-20 14:33 1505JDBC当中的批处理 在对数据库进行批量操作时,应分析操作的 ... -
大批量工具的思考
2010-06-20 14:32 921大批量工具的思考 大批量工具的思考:大批量处理工具,适用于数 ... -
Unicode、GBK、UTF-8、ASCII的编码简介
2010-06-20 14:30 3478Unicode、GBK、UTF-8、ASCII的编码简介 ... -
java中的编码简介
2010-01-16 16:48 1389Unicode、GBK、UTF-8、ASCII的编码简介 ... -
大批量工具的思考
2010-01-15 19:51 1003大批量工具的思考 大批量工具的思考:大批量处理工具,适用于数 ... -
java当中的批处理
2010-01-15 19:44 10722在对数据库进行批量操作时,应分析操作的前后相关性,如果属于大批 ... -
接口模块的定义
2010-01-15 19:34 12731 作为接口模块,必须要在设计时仔细逐一分析消息的类型。包括: ...
相关推荐
Java开发乱码问题解决方法汇总 ...Java开发乱码问题解决方法汇总中,我们总结了七种常见的解决方法。这些方法可以帮助读者避免乱码问题的发生。如果读者在实际开发中遇到乱码问题,可以尝试使用这些方法来解决问题。
总之,解决Java中的URL中文乱码问题需要理解URL编码的原理,并在客户端和服务器端采取相应的措施,确保编码和解码的一致性。无论是通过JavaScript编码、Java服务器端解码,还是调整服务器配置,关键在于确保字符集的...
Java 乱码问题是 Java 开发中常见的问题之一,解决这个问题需要了解 Java 的编码方式、JSP 中文乱码问题、Tomcat 5.5 中文乱码问题、JDBC ODBC Bridge 的 Bug 及其解决方法、Solaris 下 Servlet 编程的中文问题及...
本文将深入分析Java中文乱码问题的根本原因,介绍各种编码格式的区别和应用场景,并提供解决乱码问题的方法和经验。 在Java中,常见的编码格式有: * ASCII码:总共有128个,用一个字节的低7位表示,0~31是控制...
JAVA 中文乱码解决问题 JAVA 中文乱码问题是开发过程中常见的问题之一,解决这个问题需要了解乱码产生的原因,然后对症下药。下面我们对容易产生乱码问题的场景进行分析,并提出解决方案。 1. 以 POST 方法提交的...
通过上述方法,可以有效解决Java在处理中文字符时可能出现的乱码问题,确保程序在各种环境下正确显示中文。在开发过程中,保持编码一致性,理解和利用Java提供的字符编码工具,是预防和解决这类问题的关键。
本文将深入探讨几种解决Java中中文乱码问题的方法,并以MyEclipse为开发环境,结合实际示例进行讲解。 1. 文件读写中的乱码: 当Java程序读取或写入包含中文字符的文件时,需要设置正确的字符编码。例如,使用`...
### Java中文乱码的解决方法 ...以上三种方法都是解决Java Web应用中中文乱码的有效方案,具体选择哪种方式取决于应用程序的具体需求和技术栈。在实际开发中,可以根据项目的特点灵活选择适合的解决方案。
针对上述原因,我们可以采取以下措施来解决Java中文乱码问题: 1. **统一编码格式**:确保开发环境中所有相关的编码设置都使用统一的标准,如UTF-8。这包括文件保存时的编码、编译器的编码设置以及JVM的默认字符集...
通过上述方法,我们可以有效地解决Java编程中常见的乱码问题。关键在于确保整个流程中(包括文件、网络传输、数据库等)使用的字符集编码保持一致。此外,还应养成良好的编码习惯,如使用标准的字符集编码(如`UTF-8...
Java乱码问题解决方法,java乱码怎么解决,java项目乱码,java乱码处理,
总之,解决Java中的中文乱码问题,关键在于识别出问题所在的具体环节,然后根据该环节的特点选择合适的编码设置。理解字符编码的工作原理,以及如何在Java中操作字符编码,对于避免和解决乱码问题至关重要。在实际...
四、解决乱码问题的方法 要解决乱码问题,我们需要了解 Java 处理字符的原理,并了解编译和运行时的字符编码转换过程。在编译时,需要指定正确的编码类型;在运行时,需要正确地处理字符编码转换,以避免乱码的出现...
Java 生成 PDF 文件,解决中文乱码问题是 Java 编程中常见的问题。解决这个问题的关键是正确地设置中文字体,以避免乱码问题。本文将通过一个完整的示例代码,详细讲解如何使用 iText 库生成 PDF 文件,解决中文乱码...
在Java编程中,中文乱码问题是一个常见的困扰开发者的问题,特别是在处理输入输出或者网络通信时。这个问题涉及到字符编码的理解和正确使用。以下是对这个主题的详细解析: 首先,我们需要了解字符编码的基础知识。...
java编码中的中文问题是一个老生常谈的问题了,每次遇到中文乱码LZ要么是按照以前的经验修改,要么则是baidu.com来解决问题。阅读许多关于中文乱码的解决办法的博文后,发现对于该问题我们都(更加包括我自己)没有...
为了解决这个问题,我们可以统一Java编译器和源文件编码,例如在IDEA中设置项目编码为UTF-8,并在POM.XML中配置UTF-8编码: ```xml <!-- java 源文件编码 --> <project.build.sourceEncoding>UTF-8 ...
Java和C++之间进行Socket通信时,可能会遇到乱码问题,主要是由于编码格式不一致导致的。Java默认使用UTF-8编码,而C++在Windows XP环境下可能使用GBK编码。解决这个问题的关键在于确保数据在传输过程中保持正确的...
总结来说,处理Java中ZIP文件的中文乱码问题,关键在于明确指定字符集,通常是UTF-8,无论是使用Java内置的API还是第三方库。同时,理解文件系统的编码和压缩/解压过程中的字符编码转换也非常重要。通过这种方式,...