UDP SocketException on EndReceiveFrom (C#)

本文关键字:EndReceiveFrom SocketException on UDP | 更新日期: 2023-09-27 18:14:45

我目前正在用c#编写一些异步UDP网络代码。我来回发送小数据包(到目前为止每个数据包的数据量都小于50字节),我的第一个想法是将它们分成两个不同的数据包,仍然作为一个数据包发送,但作为两个数据包接收。因此,一个报头或一个额外的信息包总是添加到实际包的开始。它将包含ID和数据长度。

所以我认为我可以在接收端(异步接收)上分割它,首先接收标题,然后接收实际信息。这样我就不必担心数据包和"数据包头"之间的顺序。

所以我写的代码基本上是这样的:客户端向服务器发送30个字节的数据,其中前3个字节是数据包头。

服务器将调用(PACKET_HEADER_SIZE = 3):

socket.BeginReceiveFrom(state.Buffer, 0, PACKET_HEADER_SIZE, SocketFlags.None, ref endPoint, ReceivePacketInfo, state);

然后接收数据:

private void ReceivePacketInfo(IAsyncResult ar)
{
    StateObj state = (StateObj) ar.AsyncState;
    int bytesRead = socket.EndReceiveFrom(ar, ref endPoint);
    state.BytesReceived += read;
    if (state.BytesReceived < state.Buffer.Length)
    {
        _socket.BeginReceiveFrom(state.Buffer, state.BytesReceived, state.Buffer.Length - state.BytesReceived, SocketFlags.None, ref endPoint, ReceivePacketInfo, state);
    }
    else
    {
        //my thought was to receive the rest of the packet here
    }
}

但是当调用socket.EndReceiveFrom(ar)时,我得到一个SocketException:

"在数据报套接字上发送的消息大于内部消息缓冲区或其他网络限制,或者用于接收数据报的缓冲区小于数据报本身"

现在我有几个问题。

在我调用EndReceiveFrom之前,我必须确保我收到整个包(在这种情况下头和包)吗?

我可以假设我将要么得到整个包在一个去或得到什么,使我的if语句在ReceivePacketInfo将是多余的(只要它的大小小于最大包的大小,当然)?

如果我不能,有没有好的方法来解决我的问题?我可以标记所有的包头和所有的包,我想可以把它们映射到一起。我也可以尝试有一个标准化的"包结束",这样我就可以一直读到包的末尾。

提前感谢您的帮助!

UDP SocketException on EndReceiveFrom (C#)

我可以假设我要么一次得到整个包,要么什么也得不到吗

这几乎是唯一的事情,UDP可以保证-包的内容。如果数据包被接收,则保证具有相同的大小和相同的内容。所以你必须确保你的缓冲区足够大,可以容纳一个数据包。

不能保证数据包的顺序和传输本身。这取决于您和您的应用程序来处理丢失的数据包和乱序的数据包。