如果缓冲区太小,防止异常?

时间:2012-02-12 01:51:11

标签: c# arrays sockets asynchronous udp

每当我的服务器应用程序收到一个对缓冲区来说太大的数据包时,它在调用Socket.EndReceiveFrom时崩溃。这就是我的代码:

static EndPoint remote = new IPEndPoint(IPAddress.Any, 0);
static Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

static void Main(string[] args)
{
    socket.Bind(new IPEndPoint(IPAddress.Any, 1234));
    Receive();
    Console.WriteLine("Receiving ...");

    for (; ; ) ;
}

static void Receive()
{
    byte[] buffer = new byte[64];
    socket.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref remote, ReceiveFromCallback, buffer);
}

static void ReceiveFromCallback(IAsyncResult result)
{
    EndPoint theRemote = new IPEndPoint(IPAddress.Any, 0);
    byte[] buffer = (byte[])result.AsyncState;

    // the following for loop is irrelevant for this question - it simply outputs the received data as hex numbers
    for (int x = 0; x < 8; x++)
    {
        Console.Write("  ");
        for (int y = 0; y < 8; y++)
        {
            string hex = Convert.ToString(buffer[(x * 8) + y], 16);
            Console.Write((hex.Length == 1 ? "0" : "") + hex + " ");
        }
        Console.WriteLine();
    }

    // the following line of code crashes the application if the received message is larger than 64 bytes
    socket.EndReceiveFrom(result, ref theRemote);
}

如果收到的数据包大于64字节,我的应用程序抛出SocketException,说明如下:

  

通过数据报套接字发送的消息太大了   内部数据缓冲区或其他网络限制,或使用的缓冲区   接收数据报太小了。

请注意,这不是原始邮件文本。由于我正在使用德语版的Visual Studio,我不得不将其翻译回来。

ReceiveFromCallback的“buffer”变量只包含消息的前64个字节(如果它大于该字节)。因此,检查“buffer”是否包含超过64个字节不是一种选择。

所以我的问题是:

我是否需要调用EndReceiveFrom();为什么要这么称呼?如何检查收到的消息对于缓冲区是否太大?

1 个答案:

答案 0 :(得分:2)

From MSDN:

  

在回调方法中,调用IAsyncResult的AsyncState方法以获取传递给BeginReceiveFrom方法的状态对象。从此状态对象中提取接收Socket。获取Socket后,可以调用EndReceiveFrom方法成功完成读操作并返回读取的字节数。

因此,您应该在回调中调用EndReceiveFrom(就像您一样)。只需捕获异常,您的应用程序就不会“崩溃”。