我已經實現了多個客戶端和服務器。客戶端以2分鐘的固定間隔向服務器發送大小爲238或564的tcp數據包。數據包的結構如下c#源數組不夠長。檢查srcIndex和長度,以及陣列的下限Array.Copy
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
}
問題,我面對的是,這個代碼能夠正確地分析數據包在一定程度上。例如,第一數據包10-11服務器接收後該異常被正確但隨後解析「源陣列不夠長,檢查SRCINDEX和長度,並且該陣列的下限」在線
拋出Array.Copy(pkt, ind, pass_packet, 0, size);
的 '尺寸' 值突然跳到4096
堆棧跟蹤被以下
在System.Array.Copy(陣列sourceArray,的Int32 sourceIndex,陣列destinationArray, INT32 destinationIndex,INT32長度,布爾可靠)
在System.Array.Copy(陣列sourceArray,INT32 sourceIndex,陣列destinationArray,INT32 destinationIndex,INT32長度)
在Packet_parsing.client_pkt_parsing.data_pkt_func(INT32 IND,INT32在WindowsFormsApplication1 \ packet_parser.cs中:line 357
at Datapackparser(Byte [] packet,Int32 input_length,Int32 indexno,Socket sk)在WindowsFormsApplication1 \ packet_parser.cs中的大小,字符串code_packet,Byte [] pkt,String file1) line 847
at WindowsFormsApplication1 .Form1.Listeners()在\ WindowsFormsApplication1 \ Form1.cs中:線385
在System.Threading.ThreadHelper.ThreadStart_Context(對象狀態)
在System.Threading.ExecutionContext.Run(的ExecutionContext的ExecutionContext,ContextCallback回調,對象的狀態,布爾ignoreSyncCtx)
在System.Threading.ExecutionContext.Run(的ExecutionContext的ExecutionContext,ContextCallback回調,對象狀態)
在System.Threading.ThreadHelper。ThreadStart()
所以,任何人都可以幫我解決這個錯誤?
可能不是直接相關的,但是你的循環代碼被嚴重破壞 - 你可能會對'networkStream.Read'發出多次調用,並且只保留'stream_size'中返回的最後一個值。而且你總是從緩衝區開始覆蓋。你應該積累'stream_size'並將它作爲第二個參數(而不是'0')傳遞給'Read'(並且相應地調整長度) –