这几天修改之前一位同事的代码,有关和第三方的服务器设备通讯的,程序报错,接收到XML字符格式错误。
经过排查,发现问题如下:
1、同事只申请了4096个字节的长度来存储接收来的数据,现第三方修改了xml格式,导致长度远远超过了预计的长度。4096个字节不够了。。
2、同事把报文的前4个字节的内容直接抛弃不要了,想来应该是报文的长度。
既然发现问题,直接上手修改:
1、确认了前4个字节为报文的长度,然后采用循环接收的方式接收所有数据。
核心代码如下:
1 byte[] MesgLength = new byte[4]; 2 int receiveNum = clientsocket.Receive(MesgLength, 4, 0); //前4位为信息的长度 3 int Length = BitConverter.ToInt32(MesgLength, 0); 4 5 result = new byte[Length]; 6 7 int tempLength = Length; 8 int pos = 0; 9 10 int receiveBytesNum = 0; 11 while (tempLength > 0) 12 { 13 receiveBytesNum = clientsocket.Receive(result, pos, tempLength, SocketFlags.None); 14 tempLength -= receiveBytesNum; 15 pos += receiveBytesNum; 16 } 17 string str = Encoding.ASCII.GetString(result);
2、在修改的过程中,发现了同事写的这么一行代码:
return ((i & 0xff) << 24) + ((i & 0xff00) << 8) + ((i & 0xff0000) >> 8) + ((i >> 24) & 0xff);
发送数据的时候使用的函数,对报文的前4个字节的处理。当时是一阵懵逼的,移位运算多少年没碰过了,早还给老师了,这段代码到底是"WTF”。
得了,反正这段代码和我要修改的没啥关系,事不关己高高挂起。不研究了。。。
release版本,进行测试,挂了,报了这么一个错误:
error:Arithmetic operation resulted in an overflow.
再跟其他同事沟通后才知道,第三方是Unix环境,前4个字节数据接收后要进行大小端转换。
网上查了查大小端转换的资料,突然想到,刚刚同事的那段“WTF”的代码,是不是就是干这工作的。。。
测试下,果不其然,真的是这个功能。
不过,网上查资料,还是查到了个新东西,也是大小端转换的。
Array.Reverse()
这个函数嘛,比那个"WTF"的代码好看多了,恩,阅读性很强。
先测试下,测试代码如下:
int i = 256; byte[] Header = BitConverter.GetBytes(i);
foreach (byte b in Header)
{
Console.Write(b + ",");
}
Console.WriteLine();
Array.Reverse(Header); foreach (byte b in Header) { Console.Write(b + ","); } Console.WriteLine(); i = ((i & 0xff) << 24) + ((i & 0xff00) << 8) + ((i & 0xff0000) >> 8) + ((i >> 24) & 0xff); byte[] HeaderNew = BitConverter.GetBytes(i); foreach (byte b in HeaderNew) { Console.Write(b + ","); } Console.WriteLine(); Console.ReadKey();
结果:
0,1,0,0,
0,0,1,0,
0,0,1,0,
一样嘛……
修改代码,搞定收工!
事情本该就这么结束了,突然大脑来了一份无限感慨。。。。
我们这些使用高级语言编程的程序员,尤其是对.Net Framework依赖性很强的我们,基本的逻辑运算,我们还记得多少,移位运算,曾是学习编程里异常重要的一部分内容,已经被包装的完全不需要写移位运算符计算了,一个函数搞定一切。到头来,真正看到这段代码的时候,真的只剩下一句感叹:“WTF”。。。。
太过依赖代码库,我们就真的成为码农了。。。。
悲剧。
浙公网安备 33010602011771号