我会尽量用最短的语言来解释这个问题。我正在使用 c++ builder 2010。
我正在使用 TIdTCPServer 并将语音数据包发送到连接的客户端列表。一切正常,直到任何客户端异常断开连接,例如电源故障等。我可以通过切断连接客户端的以太网连接来重现类似的断开连接。
所以现在我们有一个断开连接的套接字,但你知道它在服务器端还没有检测到,所以服务器也会继续尝试向那个客户端发送数据。
但是,当服务器尝试向断开连接的客户端写入数据时……Write() 或 WriteLn() 在尝试写入时挂起,就像在等待某种写入超时。这会挂起空洞数据包分发过程,从而在向所有其他客户端的数据传输中产生延迟。几秒钟后,“套接字连接已关闭”异常被引发并且数据流继续。
这是代码
try
{
EnterCriticalSection(&SlotListenersCriticalSection);
for(int i=0;i<SlotListeners->Count;i++)
{
try
{
//Here the process will HANG for several seconds on a disconnected socket
((TIdContext*) SlotListeners->Objects[i])->Connection->IOHandler->WriteLn("Some DATA");
}catch(Exception &e)
{
SlotListeners->Delete(i);
}
}
}__finally
{
LeaveCriticalSection(&SlotListenersCriticalSection);
}
好的,我已经有一个保持活动机制,可以在 n 秒不活动后断开套接字。但是你可以想象,这个机制仍然不能与这个广播循环完全同步,因为这个广播循环几乎一直在运行。
那么我可以通过 iohandler 或其他方式指定任何写入超时吗?我已经看到很多关于“检测断开的 tcp 套接字”的线程,但我的问题略有不同,我需要在写入尝试期间避免挂断几秒钟。
那么有什么解决办法吗?
或者我应该考虑对这种数据广播使用一些不同的机制,例如广播循环将数据包放在某种 FIFO 缓冲区中,客户端线程不断检查可用数据并挑选并将其传递给自己?这样,如果一个线程挂起,它将不会停止/延迟整个分发线程。
请问有什么想法吗?感谢您的时间和帮助。
问候
果酱