c# - 下一个排队数据报的大小 - UDP

标签 c# .net sockets udp datagram

我正在使用 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/

相关文章:

c# - 反序列化 JSON 字符串 - 列表/数组

c# - XML序列化查询

java - 安卓蓝牙;是否可以?

c# - 从 WPF 中的 Image 标记修改图像

c# - 根据其值设置 DataGrid 单元格背景(C#、WPF)

c# - 如何将 HostControl 实例传递给 TopShelf 中的自定义主机服务?

android - 将 Network SocketFactory 与 SSL 结合使用

linux - Socket Send(2) - 如何从服务器向客户端发送错误信息

c# - 从 C# 程序运行 C# 编译器

.net - 尝试将 AutoMapper 添加到 .NetCore1.1 - 无法识别 services.AddAutoMapper()