在玩够了异步套接字编程之后,我注意到服务器正在接收分块的有效负载(即:多个完整的有效负载位于同一个缓冲区中)。所以我想出了以下内容:
if (bytes_to_read > 0)
{
while (bytes_to_read > 0)
// Get payload size as int.
// Get payload in byte format.
// Do something with payload.
// Decrease the amount of bytes to read.
}
// Wait for more data.
}
然后我注意到数据包碎片(即:我认为完整的有效载荷并不总是这样),这将之前的代码更改为:
if (bytes_to_read > 0)
{
while (bytes_to_read > 0)
{
// Get payload size as int.
// Check if the payload size is less than or equal to the amount of bytes left to read.
if (payload_size <= bytes_to_read)
{
// Get payload in byte format.
// Do something with payload.
// Decrease the amount of bytes to read.
}
else
{
// We received a fragmented payload.
break;
}
}
if (bytes_to_read == 0)
{
// Wait for more data.
}
else if (bytes_to_read > 0)
{
// Wait for more data where we left off. ***
}
else
{
// Something awful happened.
}
}
*** 我什至不知道该怎么做,想看看它的代码。我有一个想法,它涉及将未完成的有效负载复制到缓冲区的开头,然后从那里拾取。
我包含的伪代码基于我正在使用的 Begin* End* 方法(我知道我应该使用此处找到的 *Async 方法集 -> http://msdn.microsoft.com/en-us /library/system.net.sockets.socketasynceventargs.aspx <- 但我认为我的整体问题仍然适用)。
我正在寻找 2 个问题的答案——即:
- 这种方法是正确的还是我错过了什么?
- 在 C# 中处理数据包碎片的工作示例是什么样的?
编辑:我正在使用原始套接字。
提前感谢您的所有帮助。
编辑:John Saunders 和 Greg Hewgill 提出了将数据视为流的观点,但这并没有为我提供如何处理有时被碎片化的最后一个分块有效负载的具体示例。
编辑:我在这里阅读了 Jon Skeet 的答案,该答案与我看到的其他答案基本相同,但它对我没有多大帮助,因为我已经得到了我必须做的事情,但不知道如何去做。
编辑:要详细说明碎片的含义,请考虑以下接收缓冲区:
- 224TEST3foo3bar
- 224TEST3foo3bar224TEST3foo3bar
- 224TEST3foo3bar224TEST3foo
- 3bar224TEST3foo3bar
编辑:我发现这个和这个导致我来到这里。Vadym Stetsiak几乎清除了所有问题(他是我一直在寻找的答案之一)。