问题描述
我正在尝试解码服务器(TCP客户端)响应。
在服务器手册中,以下是规则:
Octet 001 : Command code
Octet 002-005 : Serial number
Octet 006 : MSB block number
Octet 007 : LSB block number
Octet 008 : 8 least significant bits of the first visible channel counter,nth interval (binary).
Octet 009 : MSN: 4 most significant bits of the first visible channel counter,nth interval (binary).
LSN: 4 most significant bits of the second visible channel counter,nth interval (binary).
Octet 010 : 8 least significant bits of the second visible channel counter,nth interval.
Octet 011 : 8 least significant bits of the third visible channel counter,nth interval.
Octet 012 : MSN: 4 most significant bits of the third visible channel counter,nth interval (binary).
LSN: 4 most significant bits of the first visible channel counter,nth + 1 interval (binary).
Octet 013 : 8 least significant bits of the first visible channel counter,nth + 1 interval (binary),follow the rest of intervals.
Octet 254 : 8 least significant bits of the third visible channel counter,nth + 54 interval (binary).
Octet 255 : MSN: 4 most significant bits of the third visible channel counter,nth + 54 interval (binary).
LSN: 4 most significant bits of the first visible channel counter,nth + 55 interval (binary).
Octet 256 : 8 least significant bits of the first visible channel counter,nth + 55 interval (binary).
Octet 257 : CRC LSB
Octet 258 : CRC MSB
服务器响应示例:
524009232300020700001c000700001d0600001c000600001c0700001c000700001c0700001d000800001c0700001c000700001c0600001d000800001c0700001c000800001c0800001c000600001c0600001d000600001c0600001c000500001c0800001d000900001c0b00001c000d00001c0b00001d000e00001c0e00001c000d00001c0e00001c000d00001d0e00001c000e00001c0d00001d000d00001c0e00001c000e0000220e000024000e0000230e000024000d0000230d000024000c0000230f000024000e0000230a000024000a0000230900002400090000230c000024000e0000230e000024000d0000230c000024000c0000230e000026000e7f3b
第一个八位位组检查是命令52。八位位组2-5检查序列号是40092323。但是服务器响应的其余部分,我都不知道如何解码。
解决方法
尝试以下。字节(7 + [41 * 6] + 2)= 255或(7 + [82 * 3] + 2)= 255:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
using System.Runtime.InteropServices;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string input = "524009232300020700001c000700001d0600001c000600001c0700001c000700001c0700001d000800001c0700001c000700001c0600001d000800001c0700001c000800001c0800001c000600001c0600001d000600001c0600001c000500001c0800001d000900001c0b00001c000d00001c0b00001d000e00001c0e00001c000d00001c0e00001c000d00001d0e00001c000e00001c0d00001d000d00001c0e00001c000e0000220e000024000e0000230e000024000d0000230d000024000c0000230f000024000e0000230a000024000a0000230900002400090000230c000024000e0000230e000024000d0000230c000024000c0000230e000026000e7f3b";
byte[] bytes = input.Select((x,i) => new { nibble = x,index = i }).GroupBy(x => x.index / 2).Select(x => byte.Parse(x.First().nibble.ToString() + x.Last().nibble.ToString(),NumberStyles.HexNumber)).ToArray();
Test test = new Test(bytes);
test.Print();
Console.ReadLine();
}
}
public class Test
{
public byte commandCode { get; set; }
public int serialNumber { get; set; }
public Int16 blockNumber { get; set; }
public List<List<int>> intervals { get; set; }
public Int16 crc { get; set; }
public Test(byte[] input)
{
intervals = new List<List<int>>();
commandCode = input[0];
serialNumber = BitConverter.ToInt32(input,1);
blockNumber = BitConverter.ToInt16(input,5);
crc = BitConverter.ToInt16(input,256);
int channel1 = 0;
int channel2 = 0;
for (int i = 0; i < 41; i++)
{
//even
channel1 = ((input[(6 * i) + 8] << 4) & 0xF0) + input[(6 * i) + 7];
channel2 = ((input[(6 * i) + 8] << 8) & 0x0F) + input[(6 * i) + 9];
List<int> interval = new List<int>();
interval.AddRange(new List<int> { channel1,channel2 });
intervals.Add(interval);
//odd
channel1 = ((input[(6 * i) + 11] << 4) & 0xF0) + input[(6 * i) + 10];
channel2 = ((input[(6 * i) + 11] << 8) & 0x0F) + input[(6 * i) + 12];
interval = new List<int>();
interval.AddRange(new List<int> { channel1,channel2});
intervals.Add(interval);
}
}
public void Print()
{
Console.WriteLine("Command Code : {0}",commandCode);
Console.WriteLine("Serial Number : {0}",serialNumber);
Console.WriteLine("Block Number : {0}",blockNumber);
Console.WriteLine("CRC : {0}",crc.ToString("X4"));
for (int i = 0; i < 82; i++)
{
Console.WriteLine("Interval : {0},Channel 1 : {1},Channel 2 : {2}",i + 1,intervals[i][0],intervals[i][1]);
}
}
}
}
由于每个间隔为3个字节,因此可以这样编写for循环
for (int i = 0; i < 82; i++)
{
//even
channel1 = ((input[(3 * i) + 8] << 4) & 0xF0) + input[(3 * i) + 7];
channel2 = ((input[(3 * i) + 8] << 8) & 0x0F) + input[(3 * i) + 9];
List<int> interval = new List<int>();
interval.AddRange(new List<int> { channel1,channel2 });
intervals.Add(interval);
}
,
我读取服务器的方法:
public string read()
{
// CREATE TCP CLIENT
TcpClient client = new TcpClient("SERVER_IP",2180);
NetworkStream ns = client.GetStream();
// SEND COMMAND
var command = StringToByteArray("COMMAND_TO_SEND");
ns.Write(command,command.Length);
// GET SERVER RESPONSE
byte[] bytesToRead = new byte[client.ReceiveBufferSize];
int bytesRead = ns.Read(bytesToRead,client.ReceiveBufferSize);
// DECODE ANSWER
string returndata = BitConverter.ToString(bytesToRead,bytesRead).Replace("-","");
// Close connection
client.Close();
return returndata;
}
public byte[] StringToByteArray(string hex)
{
return Enumerable.Range(0,hex.Length).Where(x => x % 2 == 0).Select(x => Convert.ToByte(hex.Substring(x,2),16)).ToArray();
}