我正在使用 System.Net.Sockets
Socket
类来接收 UDP 数据报。
我想知道收到的数据报的确切长度,以便检查数据报的有效性。
Socket.Receive(Byte())
方法文档说:
If you are using a connectionless Socket, Receive will read the first queued datagram from the destination address you specify in the Connect method. If the datagram you receive is larger than the size of the buffer parameter, buffer gets filled with the first part of the message, the excess data is lost and a SocketException is thrown.
Socket.Available
属性给出了可供读取的字节总数,这是所有排队数据报的总大小。
有没有办法找出下一个数据报的大小?
public static void Receive()
{
Byte[] buf, discardbuf;
const int paklen = 32; //correct packet length
int l;
buf = new Byte[paklen];
discardbuf = new Byte[4096];
while (rcv_enable)
{
l = soc.Available;
if (l == 0) continue;
if (l == paklen) soc.Receive(buf); //receive the correct packet
else soc.Receive(discardbuf); //discard otherwise
Thread.Sleep(200);
Console.WriteLine("Received {0}", l);
};
}
最佳答案
我假设您已经开发了自己的协议(protocol)并且期望数据报的大小是已知的,并且您想要保护自己免受流氓数据包的侵害。
由于性能似乎是一个问题并且您想避免异常,我会看一下 overload of Receive它返回原始套接字错误而不是抛出异常。 MSDN 文档确实(错误地?)声明此方法也会引发异常,但我认为情况并非如此。这绝对值得一试。
SocketError error;
byte[] buffer = new byte[512]; // Custom protocol max/fixed message size
int c = this.Receive(buffer, 0, buffer.Length, SocketFlags.None, out error);
if (error != SocketError.Success)
{
if(error == SocketError.MessageSize)
{
// The message was to large to fit in our buffer
}
}
使用已知合理大小的缓冲区并使用重载来检查 SocketError 错误代码以确定读取是否成功或是否应该丢弃包。
但是,如果您自己的协议(protocol)可以发送未知大小的数据报,达到最大数据报大小的限制,您别无选择,只能分配一个足够大的缓冲区来容纳最大的数据包 (65k)(您可以使用缓冲区池来根据您的代码避免内存问题)。
另请查看 SocketFlags enum ,它包含一些您可能感兴趣的成员,例如 Partial 和 Peek 成员。
关于c# - 下一个排队数据报的大小 - UDP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8458963/