포트를 청취하고 일부 패킷을 수신하는 응용 프로그램을 작성했습니다. 사용자 정의 된 프로토콜에 따르면 패킷 길이는 49 바이트에서 1500 바이트까지입니다. 패킷. 49 바이트 패킷과 더 큰 패킷의 데이터를 해석하고 처리해야하는 방식이 다릅니다.TCP 클라이언트에서 데이터를 수신 할 때 오류가 발생했습니다.
문제는 내가 1374 바이트 미만의 패킷을 모두 받았을 때 패킷의 길이가 길어지면 다음 예외가 발생하고 내 데이터의 마지막 4 바이트가 손실된다는 것입니다. 1384byte 패킷 및 마지막 4 바이트 손실)
제기 된 예외 : 인덱스가 범위를 벗어났습니다. 음수가 아니어야하며 콜렉션의 크기보다 작아야합니다. 매개 변수 이름 : startIndex
각 49 바이트 패킷에는 35 바이트의 데이터가 있으며 더 큰 패킷의 데이터 길이는 (압축으로 인해) 비 결정적입니다.
마지막 4 바이트가 별도의 "바이트"및 "결과"변수에 있음을 알았습니다. 즉, 새 패킷처럼 취급되고 해당 패킷에 연결되어 있지 않음을 의미합니다. 여기
데이터 수신에 대한 코드입니다 : 그렉 제안 및 나의 연구에 따르면TcpClient Client = obj as TcpClient;
EndPoint ep = Client.Client.RemoteEndPoint;
List<Byte> result = new List<byte>();
result.Capacity = 2000;
try
{
NetworkStream stream = Client.GetStream();
int i = 49;
while ((i = stream.Read(bytes, 0,49)) != 0)
{
for (int id = 0; id < i; id++)
{
result.Add(bytes[id]);
}
//reading data length to determine packet length
byte[] tmp = new byte[2];
tmp = BitConverter.GetBytes(BitConverter.ToUInt16(result.ToArray(), 9));
if (BitConverter.IsLittleEndian)
{
Array.Reverse(tmp);
}
Int16 l = BitConverter.ToInt16(tmp, 0);
if (l>35)
{
stream.Read(bytes, result.Count, l - 35);
for (int id = 49; id <((l-35)+49); id++)
{
result.Add(bytes[id]);
}
if (this.TCPDataReceivedHandler != null)
{
this.TCPDataReceivedHandler(ep, result.Count, result.ToArray());
result.Clear();
Array.Clear(bytes, 0, 2000);
result.Capacity = 2000;
}
}
else
{
if (this.TCPDataReceivedHandler != null)
{
this.TCPDataReceivedHandler(ep, result.Count, result.ToArray());
result.Clear();
Array.Clear(bytes, 0, 2000);
result.Capacity = 2000;
}
}
}
System.Diagnostics.Debug.WriteLine("client Close");
Client.Close();
}
catch (System.Exception ex)
{
throw ex;
}
finally
{
Client.Close();
this.clients.Remove(Client);
}
을, 나는 또한 다음과 같은 방법을 사용하여 시도 : TCP를 사용하는 경우
NetworkStream stream = Client.GetStream();
int bytesread = 0, OffsetTemp = 0;
while (stream.CanRead)
{
OffsetTemp = 0;
bytesread += stream.Read(bytess, OffsetTemp, 11);
OffsetTemp = OffsetTemp + 11;
byte[] tmp = new byte[2];
tmp = BitConverter.GetBytes(BitConverter.ToUInt16(bytess.ToArray(), 9));
if (BitConverter.IsLittleEndian)
{
Array.Reverse(tmp);
}
Int16 l = BitConverter.ToInt16(tmp, 0);
bytesread += stream.Read(bytess, OffsetTemp++, 11 + l + 3);
for (int id = 0; id < l + 14; id++)
{
result.Add(bytess[id]);
}
if (this.TCPDataReceivedHandler != null)
{
this.TCPDataReceivedHandler(ep, result.Count, result.ToArray());
result.Clear();
Array.Clear(bytess, 0, 2000);
}
}
고마워,하지만 내 패킷의 데이터 길이 필드에주의하지 않고 stream.Read()에서 계속 읽으면 패킷이 서로 섞이지 않는 것을 어떻게 확인할 수 있습니까? 패킷이 단시간에 연속적으로 전송됩니다. –
프로토콜에 다음과 같은 데이터 블록의 길이를 지정하는 헤더가있는 것 같습니다. 따라서 현재 블록에 대해 그 정도만 읽은 다음 상단으로 돌아가 다음 블록의 길이 헤더를 읽습니다. –
친애하는 그렉, 나는 당신의 제안을 사용했지만 작동하지 않았지만 여전히 1380 바이트 이상의 데이터를 수신하는 데 문제가 있습니다. –