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

发布于 2024-12-20 14:01:18 字数 943 浏览 2 评论 0原文

我正在使用 System.Net.Sockets Socket 类来接收 UDP 数据报。 我想知道收到的数据报的确切长度,以便检查数据报的有效性。

Socket.Receive(Byte()) 方法文档说:

如果您使用无连接套接字,Receive 将从您在 Connect 方法中指定的目标地址读取第一个排队的数据报。如果您收到的数据报大于缓冲区参数的大小,缓冲区将被消息的第一部分填充,多余的数据将丢失并引发 SocketException。

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);
    };
}

I am using System.Net.Sockets Socket class to receive UDP datagrams.
I wanted to know the exact length of the datagram received in order to check the validity of the datagram.

Socket.Receive(Byte()) method documentation says:

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 property gives the total of bytes available to be read, This is sums up the size of all queued datagrams.

Is there a way I can find out the size of the next datagram?

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);
    };
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

2024-12-27 14:01:19

我假设您已经开发了自己的协议,并且期望收到预先已知大小的数据报,并且您希望防范恶意数据包。

由于性能似乎是一个问题,并且您想避免异常,因此我会看看 接收的重载返回原始套接字错误而不是抛出异常。 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 错误代码,以确定读取是否成功或是否应删除包。

但是,如果您自己的协议可以发送未知大小的数据报,直到达到最大数据报大小的限制,您除了分配足够大的缓冲区以容纳最大数据包(65k)之外别无选择(您可以使用缓冲池来避免内存问题取决于您的代码)。

另请查看 SocketFlags 枚举,它包含您可能感兴趣的一些成员,例如 Partial 和 Peek 成员。

I'm going to assume that you've developed your own protocol and are expecting datagrams of a pre-known size and you want to guard yourself against rogue packets.

Since performance seems to be an issue and you want to avoid exceptions I'd have a look at the overload of Receive which returns the raw socket error instead of throwing exceptions. The MSDN documentation does (incorrectly?) state that this method too will throw an exception but I don't think that is the case. It's definitely worth a try.

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
    }
}

Use a buffer of a pre-known sane size and use the overload to check the SocketError error code in order to determine whether or not the read succeeded or if you sholud drop the package.

If, however your own protocol can send datagrams of unknown sizes up to the limit of the maximum datagram size you have no choice other than allocating a buffer large enough to fit the largest packet (65k) (you could use buffer pooling to avoid memory issues depending on your code).

Also check out the SocketFlags enum, it contains some members which may be of interest to you such as the Partial and Peek members.

套路撩心 2024-12-27 14:01:19

为什么不直接检查 Receive 的返回值呢?我非常确定每次调用都会返回一个数据报。

Why not just check the return value from Receive? im quite sure each call will return one datagram.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文