我有一个c#.net4应用程序,它使用BeginReceiveFrom和EndRecieveFrom监听套接字。一切都按预期工作,直到我让机器进入睡眠状态然后恢复。
此时EndReceieveFrom执行并抛出异常(无法访问已处置的对象)。看起来插座在机器挂起时处理掉,但我不知道如何处理它。
我是否假设所有套接字都已经处理好并从头开始重新创建它们?我在跟踪确切问题时遇到问题,因为远程调试也会在暂停/恢复时中断。
答案 0 :(得分:4)
暂停/恢复期间发生的事情在很大程度上取决于您的硬件和网络设置。如果您的网卡在暂停期间未被禁用,并且暂停是短暂的,则打开的连接将在暂停/恢复时继续存在而没有任何问题(当然,打开的TCP连接可能会在另一端超时)。
但是,如果您的网络适配器在睡眠期间被禁用,或者是因为它连接到已禁用的集线器而被禁用的USB适配器,或者您的计算机从DHCP获取新的IP地址,或者您的无线适配器重新连接对于不同的接入点等,那么所有当前的连接都将被丢弃,监听套接字将不再有效等等。
这是不特定于睡眠/恢复。网络接口可以随时出现和关闭,您的代码必须处理它。您可以使用USB网络适配器轻松模拟此情况,例如:把它从你的计算机中拉出来,你的代码必须处理它。
答案 1 :(得分:0)
我在暂停/恢复和套接字方面遇到过类似问题(在.NET 4和Windows 8下,但我怀疑不限于这些)。
具体来说,我有一个只接收数据的客户端套接字应用程序。读取是通过BeginReceive进行回调完成的。回叫中的代码处理了典型的故障情况(例如,远程服务器正常关闭或不关闭连接)。
当客户端机器进入休眠状态时(这可能也适用于较新的Windows 8快速启动模式,这实际上只是一种睡眠/休眠状态)服务器会在几秒钟后关闭连接。然而,当客户端醒来时,异步读取回调没有被调用(我预计会发生这种情况,因为当套接字有错误条件时它应该被调用/除了有数据时被关闭)。我明确地将定时器上的代码添加到客户端以定期检查这种情况并恢复,但即使在这里(并使用Poll,Available和Connected的组合来检查连接是否已启动)客户端上的套接字STILL似乎连接,所以恢复代码永远不会运行。我想如果我尝试发送数据,那么我会收到一个错误,但正如我所说,这是严格单向的。
我最终使用的解决方案是从睡眠状态检测恢复,并在发生这种情况时关闭并重新建立我的套接字连接。有很多方法可以检测简历;在我的情况下,我正在编写Windows服务,所以我可以简单地覆盖ServiceBase.OnPowerEvent方法。