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 异常后是不是可以重用套接字?的主要内容,如果未能解决你的问题,请参考以下文章