2010-11-10 4 views
1

Есть ли причина, по которой Socket должна закрываться сама по себе, после 2 часов? Я получаю данные каждую секунду из этого сокета и записываю несколько крошечных «живых» данных каждые 30 секунд.Автоматическое закрытие гнезда

Перед отправкой я проверяю, если сокет все еще подключен, используя следующий метод:

public bool IsSocketReadyForWriting(Socket s) 
{ 
    try 
    { 
     if (!s.Connected) 
     { 
      Log.Info("Socket.Connected was false"); 
      return false; 
     } 

     // following line will throw if socket disconnected 
     bool poll = s.Poll(2000, SelectMode.SelectWrite); 
     if (!poll) 
     { 
     try 
     { 
      // if poll is false, socket is closed 
      Log.Info("poll is false"); 
      this.Close(); 
     } 
     catch { } 
     return false; 
     } 
     Log.Debug("still connected"); 
     return true; 
    } 
    catch (Exception ex) 
    { 
     Log.Error("Error while checking if socket connected", ex); 
     return false; 
    } 
} 

Все отлично работает около 2ч, а потом вдруг Socket.Poll возвращает ложь, и сокет закрывается.

Есть ли настройка, которая контролирует это, или я делаю что-то действительно не так?

[Редактировать]

забыл упомянуть: я контролирую как сервер и клиент на стороне ссылки. Это оба приложения C#, один из которых создает прослушивающий сокет, другой открывает соединение и отправляет данные. Они общаются без проблем в течение 2 часов (без утечек памяти и т. Д.), Затем сокет закрывается.

Когда это произойдет, я снова могу снова подключить сокет, но я просто блуждаю, если кто-нибудь знает, почему это может быть причиной этого.

+0

Является ли измеренный таймаут ровно 2 часа? Или просто вокруг? Кроме того, вы контролируете все сетевые устройства между ними? – Carlos

ответ

3

По умолчанию сокет TCP доступен для записи, если в гнезде имеется по меньшей мере один байт пространства буфер отправки. Чтобы обратить вспять это - сокет равен , а не, доступный для записи, когда в «выходной очереди» имеется достаточно не подтвержденных данных.

Это говорит о том, что вытащить wireshark или что-то другое, что Microsoft предлагает для обнюхивания пакетов и посмотреть, что происходит на проводе. Являются ли ваши биты сердечного ритма ACK -ed? Открывается ли окно приемника или оно заканчивается нулем? Или вы просто получаете явные RST или FIN от некоторого промежуточного коммутатора?

Один из способов уменьшить временную засоренную трубу - увеличить размер буфера отправки, который по умолчанию крошечный по умолчанию для Windows - 8192 iirc. См. setsockopt (у .NET, вероятно, есть версия этого) и SO_SNDBUF.

+1

Спасибо, вот и все. Мои фиктивные клиенты не читали входной поток TCP (несколько байтов/байтов состояния) вообще, поэтому мой буфер вывода на сервере был заполнен. – Groo

1

Может быть сервер, который закрывает соединение? У вас есть контроль над этим?

+0

О, забыл сказать, я контролирую как сервер, так и клиент. Это оба приложения C#. – Groo

+0

AFAIK, 2 часа - это таймаут после того, как опция SOL_KEEPALIVE отправляет свое подтверждение (см. Http://www.unixguide.net/network/socketfaq/4.7.shtml). Может быть, эта опция включена с одной стороны, а не с другой? – Simone

Смежные вопросы