[英]NetworkStream read skipping packets
我正在尝试使用 async BeginRead 来实现 TCPClient 以侦听自定义应用程序。 监听代码是这样的:
ClientState cs;
void Update()
{
lock (lockObj)
{
if (cs != null)
{
if (cs.bytesReceived > 0)
{
ReceiveNetworkMsg?.Invoke(cs.receiveBuffer, cs.bytesReceived);
Array.Clear(cs.receiveBuffer, 0, cs.bytesReceived);
cs.bytesReceived = 0;
}
}
}
}
IEnumerator ListenForData()
{
Debug.Log("Listening");
stream = client.GetStream();
cs = new ClientState(stream);
do
{
//stream.BeginRead(buffer, 0, buffer.Length, MessageReceived, client);
stream.BeginRead(cs.buffer, 0, cs.buffer.Length, new AsyncCallback(ReadCallback), cs);
yield return null;
} while (client != null);
}
void ReadCallback(IAsyncResult result)
{
ClientState cs = (ClientState)result.AsyncState;
lock (lockObj)
{
int currBytesReceived = cs.stream.EndRead(result);
Array.Copy(cs.buffer, 0, cs.receiveBuffer, cs.bytesReceived, currBytesReceived);
Debug.Log("Network receiving: " + currBytesReceived + " " + cs.bytesReceived + " bytes. " + BitConverter.ToString(cs.buffer, 0, currBytesReceived));
cs.bytesReceived += currBytesReceived;
}
}
在服务器发送一系列消息的某个时刻,接收到的字节与发送的实际字节不匹配:
Wireshark 日志:
No. Time Source Destination Protocol Length Info
35 0.619977 127.0.0.1 127.0.0.1 TCP 64 5001 → 49872 [PSH, ACK] Seq=53 Ack=140 Win=28 Len=20
0000 14 00 23 11 4a 3e 01 01 1c 10 02 00 00 00 00 00 ..#.J>..........
0010 02 01 22 00 ..".
Data: 140023114a3e01011c1002000000000002012200
[Length: 20]
No. Time Source Destination Protocol Length Info
39 0.621735 127.0.0.1 127.0.0.1 TCP 65 5001 → 49872 [PSH, ACK] Seq=73 Ack=140 Win=28 Len=21
0000 15 00 99 b2 b6 07 01 01 06 10 02 00 00 00 00 00 ................
0010 00 00 00 00 00 .....
Data: 150099b2b607010106100200000000000000000000
[Length: 21]
No. Time Source Destination Protocol Length Info
43 0.623598 127.0.0.1 127.0.0.1 TCP 65 5001 → 49872 [PSH, ACK] Seq=94 Ack=140 Win=28 Len=21
0000 15 00 99 b2 b6 07 01 01 06 10 02 00 00 00 00 00 ................
0010 00 00 00 00 00 .....
Data: 150099b2b607010106100200000000000000000000
[Length: 21]
No. Time Source Destination Protocol Length Info
47 0.625630 127.0.0.1 127.0.0.1 TCP 65 5001 → 49872 [PSH, ACK] Seq=115 Ack=140 Win=28 Len=21
0000 15 00 99 b2 b6 07 01 01 06 10 02 00 00 00 00 00 ................
0010 00 00 00 00 00 .....
Data: 150099b2b607010106100200000000000000000000
[Length: 21]
No. Time Source Destination Protocol Length Info
51 0.627592 127.0.0.1 127.0.0.1 TCP 65 5001 → 49872 [PSH, ACK] Seq=136 Ack=140 Win=28 Len=21
0000 15 00 99 b2 b6 07 01 01 06 10 02 00 00 00 00 00 ................
0010 00 00 00 00 00 .....
Data: 150099b2b607010106100200000000000000000000
[Length: 21]
No. Time Source Destination Protocol Length Info
55 0.629683 127.0.0.1 127.0.0.1 TCP 65 5001 → 49872 [PSH, ACK] Seq=157 Ack=140 Win=28 Len=21
0000 15 00 99 b2 b6 07 01 01 06 10 02 00 00 00 00 00 ................
0010 00 00 00 00 00 .....
Data: 150099b2b607010106100200000000000000000000
[Length: 21]
No. Time Source Destination Protocol Length Info
59 0.632344 127.0.0.1 127.0.0.1 TCP 65 5001 → 49872 [PSH, ACK] Seq=178 Ack=140 Win=28 Len=21
0000 15 00 99 b2 b6 07 01 01 06 10 02 00 00 00 00 00 ................
0010 00 00 00 00 00 .....
Data: 150099b2b607010106100200000000000000000000
[Length: 21]
No. Time Source Destination Protocol Length Info
65 0.634544 127.0.0.1 127.0.0.1 TCP 62 5001 → 49872 [PSH, ACK] Seq=199 Ack=166 Win=28 Len=18
0000 12 00 57 c1 55 6c 01 01 03 10 02 01 00 00 00 00 ..W.Ul..........
0010 00 02 ..
Data: 120057c1556c010103100201000000000002
[Length: 18]
日志:
Network receiving: 20 0 bytes. 14-00-9D-59-A2-54-01-01-1C-10-02-00-00-00-00-00-02-01-1F-00
Network receiving: 21 20 bytes. 15-00-99-B2-B6-07-01-01-06-10-02-00-00-00-00-00-00-00-00-00-00
Network receiving: 21 41 bytes. 15-00-99-B2-B6-07-01-01-06-10-02-00-00-00-00-00-00-00-00-00-00
Network receiving: 21 62 bytes. 15-00-99-B2-B6-07-01-01-06-10-02-00-00-00-00-00-00-00-00-00-00
Network receiving: 21 83 bytes. 15-00-99-B2-B6-07-01-01-06-10-02-00-00-00-00-00-00-00-00-00-00
Network receiving: 21 104 bytes. 15-00-99-B2-B6-07-01-01-06-10-02-00-00-00-00-00-00-00-00-00-00
Network receiving: 21 0 bytes. 12-00-57-C1-55-6C-01-01-03-10-02-01-00-00-00-00-00-02-00-00-00
Network receiving: 18 21 bytes. 12-00-57-C1-55-6C-01-01-03-10-02-01-00-00-00-00-00-02
在 20 字节消息之后,在 18 字节消息之前应该有 6 个 21 字节消息。 我的接收端首先处理前 5 个 21 字节的消息,然后由于某种原因,当它试图处理第 6 个 21 字节的消息时,它返回了正确的大小,但它得到的是 18 字节的消息。
我在这里错过了一些基本的东西吗?
网络 stream 收到 21 个字节 6 次; ClientState
在 104 和 0 之间对它们做了什么 - 取决于ClientState
,其中:我们看不到。 听起来像是一个竞争线程让ClientState
消耗了缓冲区。 但是请注意,IMO 您的期望在这里是不正确的; 我从根本上不同意以下说法:
在 18 字节 1 之前应该有 6 条 21 字节消息
我们正在查看的代码是 TCP,它处理的是流,而不是消息; 不能保证它会以 6 个 21 字节的片段到达。 它可以全部以单个 126 字节块的形式出现,也可以以 126 个单独的 1 字节块的形式出现。 您所保证的是:相同顺序的相同字节(或者如果检测到损坏的套接字,可能会失败)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.