我已经实现了多个客户端和服务器。客户端每隔2分钟向服务器发送大小为238或564的tcp数据包。数据包的结构如下
1) 数据包标头 -- 44 字节 该标头大小不会改变,并且随每个数据包一起提供。
2) 标头之后有超过 1 个数据包,这些数据包的大小为 16 或 32 字节。这些数据包的数量随着从客户端到服务器的每个数据包而变化,这些数据包的数量决定了数据包的总大小(238 或 512)。
3)最后2个字节是crc,也是固定的并且不会改变。
我的服务器接收来自客户端的数据包,并将数据包与主数据包分开,解析它们并将其写入 Excel 文件。以下是我的代码
服务器代码
private void createserver(int no_of_clients)
{
tcpListener = new TcpListener(ipAddress, Globals.port_number);
tcpListener.Start();
for (int i = 0; i < no_of_clients; i++)
{
Thread newThread = new Thread(new ThreadStart(Listeners));
newThread.Start();
}
} //End of createserver();
public void Listeners()
{
Socket socketForClient;
socketForClient = tcpListener.AcceptSocket();
if (socketForClient.Connected)
{
NetworkStream networkStream = new NetworkStream(socketForClient);
int stream_size = 0;
while (true)
{
byte[] raw_stream = new byte[1024];
do
{
try
{
stream_size = networkStream.Read(raw_stream, 0, 1024);
}
catch (IOException e)
{
if (e.InnerException is SocketException)
{
MessageBox.Show("The client has disconnected");
foreach (Socket s in active_clients)
{
if (s == socketForClient)
{
MessageBox.Show(string.Format("Client {0} has forcibly exited", s.RemoteEndPoint));
infoBox1.Text = infoBox1.Text + "\r\n" + string.Format("Client {0} has forcibly exited", s.RemoteEndPoint);
}
}
}
return;
}
}
while (networkStream.DataAvailable);
byte[] input_data = new byte[stream_size];
byte[] input_data1 = new byte[stream_size];
Array.Copy(raw_stream, 0, input_data, 0, stream_size);
if (Encoding.ASCII.GetString(input_data) != Globals.exit_code)
{
Datapackparser(input_data, input_data.Length, 0, socketForClient);
}
}
}
public static void Datapackparser(byte[] packet, int input_length, int indexno, Socket sk))
{
//remove header and crc from end of packet since I know every time it will be same
// for separating data packets and parsing them on basis of packet id which comes with every individual data packets
data_pkts_index = 44; // since data packets start at 44. 0-43 is header
int size_1_data_pkts = 0;
string pkt_ids = "";
while (data_pkts_index < tcp_pkt_size - 2)
{
// first 2 bytes of each data packet is size of that data packet 16 or 32
size_1_data_pkts = Convert.ToInt32(string.Format(BitConverter.ToString(packet, data_pkts_index + 1, 1) +
BitConverter.ToString(packet, data_pkts_index, 1)), 16);
// next 1 byte is packet id of each data packet on basis of which I parse them
pkt_ids = Convert.ToInt32(packet[data_pkts_index + 2]).ToString("X");
// this function is for parsing each data packet
data_pkt_func(data_pkts_index, size_1_data_pkts, pkt_ids, packet, imei);
data_pkts_index = data_pkts_index + size_1_data_pkts;time it will be same.
}
}
static private void data_pkt_func(int ind, int size, string code_packet, byte[] pkt, string file1)
{
byte[] pass_packet = new byte[size];
Array.Copy(pkt, ind, pass_packet, 0, size);
if (code = "a")
{ // one type of packet
}
else if (code = "dsd")
{ // 2nd type of packet
}
else if ......
{
}
// like this their are 8-9 types of data packet
}
Run Code Online (Sandbox Code Playgroud)
我面临的问题是这段代码能够在某种程度上正确解析数据包。例如,服务器接收到的前 10-11 个数据包被正确解析,但在该异常之后,“源数组不够长。检查 srcIndex 和长度,以及数组的下限”会在该行抛出
Run Code Online (Sandbox Code Playgroud)Array.Copy(pkt, ind, pass_packet, 0, size);
‘size’值突然跳到4096
堆栈跟踪如下
在System.Array.Copy(数组sourceArray,Int32 sourceIndex,数组destinationArray,Int32 destinationIndex,Int32长度,布尔可靠)
在System.Array.Copy(数组sourceArray,Int32源索引,数组destinationArray,Int32目标索引,Int32长度)
在 WindowsFormsApplication1\packet_parser.cs 中的 Packet_parsing.client_pkt_parsing.data_pkt_func(Int32 ind, Int32 size, String code_packet, Byte[] pkt, String file1) 处:第 357 行
在 WindowsFormsApplication1\packet_parser.cs 中的 Datapackparser(Byte[] packet, Int32 input_length, Int32 indexno, Socket sk) 处:第 847 行
在 \WindowsFormsApplication1\Form1.cs 中的 WindowsFormsApplication1.Form1.Listeners() 处:第 385 行
在 System.Threading.ThreadHelper.ThreadStart_Context(对象状态)
在System.Threading.ExecutionContext.Run(ExecutionContextexecutionContext,ContextCallback回调,对象状态,布尔ignoreSyncCtx)
在 System.Threading.ExecutionContext.Run(ExecutionContextexecutionContext,ContextCallback 回调,对象状态)
在 System.Threading.ThreadHelper.ThreadStart()
那么任何人都可以帮助我解决这个错误吗?
您是否在十六进制编辑器中查看过数据包,看看数据包中的数据包大小是否正确写入?我首先捕获异常并将数据包转储到文件中以供进一步检查。
另外,你确定你的数字解析代码是正确的吗?第一个“Convert.ToInt32”行很复杂,我找不到任何将“Convert.ToInt32”列出为采用两个参数的文档。我怀疑如果你修复了这条线,你就会解决问题。