如果缓冲区太小,防止异常?
每当我的服务器应用程序收到一个对于缓冲区来说太大的数据包时,它就会在调用 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();为什么要这样称呼它?如何检查接收到的消息是否对于缓冲区来说太大?
Whenever my server application receives a packet which is too big for the buffer, it crashes when calling Socket.EndReceiveFrom. This is what my code looks like:
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);
}
If the received packets is larger than 64 bytes, my application throws a SocketException saying the following:
A message which was sent over the datagram socket was too large for
the internal data buffer or another network limit, or the buffer used
for receiving the datagram was too small.
Notice that this is not the original message text. Since I'm working with the German version of Visual Studio, I had to translate it back.
ReceiveFromCallback's "buffer" variable only contains the first 64 bytes of the message if it's larger than that. So checking whether "buffer" contains more than 64 bytes is not an option.
So my questions are:
Do I need to call EndReceiveFrom(); why should it be called? How can I check whether the received message is too big for the buffer?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
来自 MSDN:
因此,您应该在回调中调用 EndReceiveFrom (就像您所做的那样)。只需捕获异常,您的应用程序就不会“崩溃”。
From MSDN:
Therefore, you should call EndReceiveFrom in the callback (like you do). Simply catch the exception and your application wont "crash".