2013-08-28 2 views
3

Я создаю клиентское серверное приложение. сервер уже разработан и находится в ожидании подключения от клиента. Теперь в разделе клиента я хотел бы сохранить соединение в течение всей жизни приложения, и соединение закрывается только при закрытии или завершении основного клиентского приложения или закрытии сервера.Tcp connection Keep alive

В настоящее время каждые 10 секунд сервер закрывает TCP connection.I попытался с

socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.KeepAlive, true); 

, но он не работает для меня .. Ниже мой код блока

public TCPStreamDevice(string RemoteIPAddress, int RemotePort, string SourceIPAddress, int SourcePortNo)   
{ 
    mIpAddress = RemoteIPAddress; 
    mPort = RemotePort; 

    mClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
    System.Net.IPEndPoint LocalEndPoint = new System.Net.IPEndPoint(System.Net.IPAddress.Parse(SourceIPAddress), SourcePortNo); 

    mClient.Bind(LocalEndPoint); 

    mDataReceivedCallback = new AsyncCallback(DataReceivedTCPCallback_Handler); 
    mBuffer = new byte[1024]; 
    Description = new DeviceDescription(); 
} 

и в у меня есть:

private void DataReceivedTCPCallback_Handler(IAsyncResult ar) 
{ 
    try 
    { 
     Socket client = (Socket)ar.AsyncState; 
     int bytesReceived = client.EndReceive(ar); 

     if (bytesReceived > 0) 
     { 
      //to know transport level errors 
      //EngineInterface.reponseReceived(mBuffer, false); 

      ReceiveCallBackFunc(mBuffer, bytesReceived); 

      client.BeginReceive(mBuffer, 0, 1024, SocketFlags.None, DataReceivedTCPCallback_Handler, client); 
     } 
     else 
     { 
      //disconnect 
      /* when there is no datapacket means no TCP connection is alive now (how can i keep Tcp alive here) */ 
     } 
    } 
} 
+1

Возможно, сервер закрывает соединение. когда превышается тайм-аут, вы ничего не можете сделать, кроме отправки некоторых данных в течение 10 секунд. Полученные 0 байтов означают, что другая сторона отключена. –

+0

есть ли способ, с помощью которого я могу возобновить сеанс TCP? –

+0

Вам нужно будет снова подключиться, когда вам нужно. Это обычное поведение для загруженных серверов. –

ответ

1

Комментарий («whrn нет пакета данных означает, что нет TCP соединение ") в вашем коде размещается там, где вы получаете пакет отключения (0 байтов) с другой стороны. Невозможно сохранить , что соединение живое, потому что другая сторона забирает, чтобы закрыть его.

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

Механизмы сохранения жизни всегда работают вместе с таймаутами - тайм-аут принудительно ", если в течение х секунд не было получено данных, закройте соединение", где keep-alive просто отправляет фиктивный пакет данных, чтобы предотвратить возникновение тайм-аута.

Внедряя протокол самостоятельно (вы работаете на уровне TCP/IP), вам нужно только реализовать keep-alive, если у вас уже есть тайм-аут, реализованный на другой стороне.

+0

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

2

Замечания и ответ выше - звучит как плохой выбор дизайна, чтобы открыть сокет на протяжении всего жизненного цикла приложения. И ожидайте, что все будет работать должным образом - вы должны создать какой-то отказоустойчивый механизм в случае, если соединение получится отброшен.

Назад к останкам: вам нужны они на обоих концах - сервер и клиент, поэтому проверьте, как сокеты установлены с обеих сторон. Я думаю, что значение по умолчанию для keep alives составляет 2 часа - это долгое время, чтобы ждать пакет keep-alive, но его можно изменить. Проверьте метод Socket.IOControl и используйте IOControlCode.KeepAliveValues со структурой, которая выглядит так (неуправляемая) http://msdn.microsoft.com/en-us/library/ms741621.aspx. Подробнее о контрольных кодах здесь: http://msdn.microsoft.com/en-us/library/system.net.sockets.iocontrolcode.aspx

0

Вы можете установить TCP keepAlives, установив IOControlCode.KeepAliveValues ​​при создании сокета на сервере. Приведенная ниже статья о кодовом проекте объясняет это очень хорошо.

Sample on How-To set keep alive values

6

В вызове SetSocketOption(), KeepAlive не действует на SocketOptionLevel.Tcp уровне, вместо того, чтобы использовать SocketOptionLevel.Socket.

SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);

+0

Вы также должны установить настройки 'keepalivetime' и' keepaliveinterval' для сокета. Поиск 'SetSocketKeepAliveValues' и' SetTcpKeepAlive' –