我尝试使用.NET库中的string
对象将byte[]
转换为ASCIIEncoder
。 string
永远不会包含非ASCII字符,但通常长度大于16.我的代码如下所示:
public static byte[] Encode(string packet)
{
ASCIIEncoder enc = new ASCIIEncoder();
byte[] byteArray = enc.GetBytes(packet);
return byteArray;
}
在方法结束时,字节数组应该满packet.Length
个字节数,但是Intellisense告诉我byteArray[15]
之后的所有字节都是字面上无法观察到的问号。我在发送之后使用Wireshark查看byteArray
,并且在另一侧收到它很好,但终端设备没有按照byteArray
中编码的说明进行操作。我想知道这是否与Intellisense有关,无法显示byteArray
中的所有元素,或者我的数据包是否完全错误。
答案 0 :(得分:2)
如果您的packet
字符串基本上包含0-255范围内的字符,则ASCIIEncoding
不是您应该使用的字符。 ASCII仅定义字符代码0-127; 128-255范围内的任何内容都会变成问号(正如您所观察到的那样),因为ASCII中没有定义字符。
考虑使用这样的方法将字符串转换为字节数组。 (这假设每个字符的序数值在0-255范围内,并且序数值是您想要的。)
public static byte[] ToOrdinalByteArray(this string str)
{
if (str == null) { throw new ArgumentNullException("str"); }
var bytes = new byte[str.Length];
for (int i = 0; i < str.Length; ++i) {
// Wrapping the cast in checked() will trigger an OverflowException
// if the character being converted is out of range for a byte.
bytes[i] = checked((byte)str[i]);
}
return bytes;
}
Encoding
类层次结构专门用于处理文本。你在这里看到的似乎不是文本,所以你应该避免使用这些类。
答案 1 :(得分:2)
标准编码器使用替换字符回退策略。如果目标字符集中不存在某个字符,则它们会对替换字符进行编码(默认情况下为&#39;?&#39;)。
对我来说,这比沉默的失败更糟糕;它的数据损坏。我更喜欢图书馆告诉我什么时候我的假设是错误的。
您可以派生一个抛出异常的编码器:
Encoding.GetEncoding(
"us-ascii",
new EncoderExceptionFallback(),
new DecoderExceptionFallback());
如果你真的只使用Unicode的ASCII范围内的字符,那么你永远不会看到异常。