TimeOut 异常后是不是可以重用套接字?

Posted

技术标签:

【中文标题】TimeOut 异常后是不是可以重用套接字?【英文标题】:Is it possible to reuse a socket after a TimedOut exception?TimeOut 异常后是否可以重用套接字? 【发布时间】:2012-05-10 20:50:21 【问题描述】:

简单地说,是否可以在捕获 TimedOut 异常后重用套接字?我该怎么做?

长篇大论:

我有 2 个线程,都使用同一个套接字。一个正在向远程服务器发送数据包(我们称之为线程 A),而另一个(线程 B)正在侦听这些已发送数据包的确认数据包。当满足某些条件时,线程 A 将暂停(使用Monitor.Wait),等待Monitor.Pulse 继续。当线程 B 收到一个数据包时,它会调用 Monitor.Pulse 并且线程 A 继续做它的事情......

问题是数据包可能会丢失,线程 B 将无限期地等待一个不会接收到的数据包,而线程 A 正在等待一个脉冲。整个程序将“阻塞”。我的第一个想法是设置接收超时并捕获相关的异常。发生这种情况时,我调用Monitor.Pulse,线程 A 可以继续,而线程 B 将继续等待另一个数据包。

但这不起作用。当异常被捕获时,套接字将关闭,当线程 A 尝试发送新数据包时应用程序将崩溃,因为它们使用的是同一个套接字。

如何防止这种行为?

【问题讨论】:

【参考方案1】:

问题是数据包可能会丢失

不,他们不能。 TCP 不会丢失数据包。如果您丢失了数据包,您的代码中有错误,或者发送者没有发送它们。这里还没有问题。

当异常被捕获时,套接字将关闭

不,不会的。只有当关闭它时它才会关闭。

当线程 A 尝试发送新数据包时,应用程序将崩溃,因为它们使用的是同一个套接字。

仅当您在捕获超时异常时关闭了套接字。所以不要那样做。

如何防止这种行为?

捕获超时异常时不要关闭套接字。

【讨论】:

【参考方案2】:

TCP 数据包不会丢失(它们可以,但这是在完全不同的层上)。 如果出现通信错误,套接字将关闭。 但是,如果您使用的是 UDP 通信并且您选择了接收超时,那么您没有理由不能重试。

签出This。 还有Read the remarks here.

【讨论】:

'不能丢失,但他们可以'只是一个矛盾的术语。当关闭它时,套接字将关闭,在其他情况下都不会。 connection 将被删除(重置),但这不会影响套接字。 不是的,包在IP层或者链路层会丢包,就是这个意思。你有没有为此投票给我?耻辱。 数据包可能会在较低层丢失,但 TDP 会重新传输它们。您关于套接字关闭的错误仍未得到纠正,实际上没有引起注意。您的链接与该问题没有任何明显关系。

以上是关于TimeOut 异常后是不是可以重用套接字?的主要内容,如果未能解决你的问题,请参考以下文章

套接字 的端口重用 作用 是啥??

requests - timeout

Jenkins SSH 插件/SSH 代理插件:异常:超时:未建立套接字

如何重用TCP套接字python

(POSIX)操作系统是不是会在进程崩溃后恢复资源?

WSA UDP 套接字无法重用,因为它强制关闭连接