简体   繁体   English

如何从套接字错误中恢复? (10040)

[英]How do I recover from a socket error? (10040)

I have a UDP sender and a UDP listener.我有一个 UDP 发送者和一个 UDP 侦听器。 Transfering messages works nicely.传输消息效果很好。 But...但...

It appears when I am overfeeding (sending sustained data quickly) the listening socket may throw on the call to ReceiveFrom with error code 10040 which means some buffer was not large enough.当我过度喂食(快速发送持续数据)时,侦听套接字可能会抛出对 ReceiveFrom 的调用,错误代码为 10040,这意味着某些缓冲区不够大。 The exception message is异常消息是

A message sent on a datagram socket was larger than the internal message buffer or some other network limit, or the buffer used to receive a datagram into was smaller than the datagram itself.在数据报套接字上发送的消息大于内部消息缓冲区或某些其他网络限制,或者用于接收数据报的缓冲区小于数据报本身。

Fair enough.很公平。 But the problem is I will then get this exception on every following call to ReceiveFrom.但问题是我会在每次调用 ReceiveFrom 时得到这个异常。 The socket appears broken.插座似乎坏了。 I am willing to accept the transfer failed but I now want to flush the socket's receive buffer and continue.我愿意接受传输失败,但我现在想刷新套接字的接收缓冲区并继续。

I can prevent this from happening by setting a substantial receive buffer size of 128K on the listening socket (as opposed to the default of 8K).我可以通过在侦听套接字上设置 128K 的大量接收缓冲区大小(而不是默认的 8K)来防止这种情况发生。 I can also fix it by having the sender pause for 1 ms after sending a chunk of 65507 bytes of a multi-chunk bulk message.我还可以通过在发送多块批量消息的 65507 字节块后让发件人暂停 1 毫秒来修复它。

But I do not feel safe.但我没有安全感。 If this exception still occurs, I want to log and continue (better luck next time).如果这个异常仍然发生,我想记录并继续(下次运气更好)。 Recreating the socket and restarting the listen thread seems blunt.重新创建套接字并重新启动侦听线程似乎很生硬。 Is there a better way?有没有更好的办法?

Something unrelated I do not like: Socket.ReceiveFrom throws an exception after the timeout.我不喜欢不相关的东西: Socket.ReceiveFrom 在超时后抛出异常。 This is stupid, timeouts are normal behavior.这很愚蠢,超时是正常行为。 I would expect a TryReceiveFrom method and I do not like using the exception handler as a flow control statement, which seems to be the only option I have.我希望有一个 TryReceiveFrom 方法,我不喜欢将异常处理程序用作流控制语句,这似乎是我唯一的选择。 Is there a better way?有没有更好的办法?

I accept now that when the buffer overruns, the socket is broken and needs to be recreated.我现在接受,当缓冲区溢出时,套接字已损坏并且需要重新创建。

The exception being thrown after a timeout of Socket.ReceiveFrom can be prevented by first checking if any data is available using the Socket.Poll method.可以通过首先使用Socket.Poll方法检查是否有任何数据可用来防止Socket.ReceiveFrom超时后引发的异常。 This has its own timeout argument.这有自己的超时参数。 So it is pointless to set ReceiveTimeout on the socket, using Poll in tandem with ReceiveFrom works much nicer.因此,在套接字上设置ReceiveTimeout是没有意义的,将PollReceiveFrom结合使用会更好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM