Я постараюсь объяснить проблему в кратчайших словах. Я использую C ++ Builder 2010.
Я использую TIdTCPServer и отправляю голосовые пакеты в список подключенных клиентов. Все работает нормально, пока любой клиент не будет отключен ненормально, например, сбой питания и т. Д. Подобное отключение можно воспроизвести, обрезав соединение Ethernet подключенного клиента.
Итак, теперь у нас есть отключенный сокет, но, как вы знаете, он еще не обнаружен на стороне сервера, поэтому сервер будет продолжать пытаться отправить данные этому клиенту.
Но когда сервер пытается записать данные в этот отключенный клиент ...... Write () или WriteLn () вешает туда при попытке записи, это похоже на ожидание некоторого тайм-аута записи. Это приводит к зависанию процесса распределения закрытых пакетов, что приводит к задержке передачи данных всем остальным клиентам. Через несколько секунд выдается исключение «Socket Connection Closed» и поток данных продолжается.
Вот код
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 секунд бездействия. Но, как вы можете себе представить, этот механизм не может синхронизироваться точно с этим циклом braodcasting, потому что этот цикл braodcast работает почти все время.
Так есть ли тайм-ауты записи, которые я могу указать, может быть через iohandler или что-то? Я видел много-много тем о «Обнаружении отсоединенного TCP-сокета», но моя проблема немного отличается, мне нужно избегать этого зависания на несколько секунд во время попытки записи.
Так есть ли решение?
Или я должен рассмотреть возможность использования какого-то другого механизма для такой трансляции данных, например, цикл широковещания помещает пакет данных в некоторый буфер FIFO, а клиентские потоки постоянно проверяют доступные данные и выбирают и доставляют их себе? Таким образом, если один поток зависнет, он не остановит / не задержит весь поток распространения.
Есть идеи, пожалуйста? Спасибо за ваше время и помощь.
Привет
Джемы