TCP Socket Соединения - PullRequest
       19

TCP Socket Соединения

4 голосов
/ 24 мая 2011

У меня есть служба Windows, которая, помимо прочего, прослушивает входящие данные с удаленного устройства с помощью библиотеки .NET System.Net.Sockets.В приведенном ниже примере только одно удаленное устройство отправляет данные каждые 60 секунд.

Время от времени эта служба останавливается, и в журналах Windows на сервере появляется сообщение (показано ниже).

The process was terminated due to an unhandled exception. 
   Exception Info: System.Net.Sockets.SocketException Stack: 
   at System.Net.Sockets.Socket.EndReceive(System.IAsyncResult) 
   at Uk.Co.RCID.MoteServer.Server.SocketListener.ReceiveCallback(System.IAsyncResult) 
   at System.Net.LazyAsyncResult.Complete(IntPtr)
   at System.Net.ContextAwareResult.CompleteCallback(System.Object) 
   at System.Threading.ExecutionContext.runTryCode(System.Object) 
   at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode, CleanupCode, System.Object) 
   at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object) 
   at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) 
   at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object) 
   at System.Net.ContextAwareResult.Complete(IntPtr) at System.Net.LazyAsyncResult.ProtectedInvokeCallback(System.Object, IntPtr) 
   at System.Net.Sockets.BaseOverlappedAsyncResult.CompletionPortCallback(UInt32, UInt32, System.Threading.NativeOverlapped*) 
   at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32, UInt32, System.Threading.NativeOverlapped*)  

Сопоставив время этого события с моим последним оператором журнала, я обнаружил, что это фатальное исключение возникает, когда удаленное устройство дважды подключается к службе за короткое время (обычно оно подключается каждые 60 секунд кнажмите данные).Вот мой последний оператор журнала перед сбоем системы.

2011-05-20 13:39:19,545 [6] INFO  Uk.Co.RCID.MoteServer.Server.SocketListener [(null)] - Waiting for a connection...
2011-05-20 13:39:19,545 [10] INFO  Uk.Co.RCID.MoteServer.Server.SocketListener [(null)] - Connection established on [10.64.128.60:11000]
2011-05-20 13:40:20,982 [6] INFO  Uk.Co.RCID.MoteServer.Server.SocketListener [(null)] - Waiting for a connection...
2011-05-20 13:40:20,982 [5] INFO  Uk.Co.RCID.MoteServer.Server.SocketListener [(null)] - Connection established on [10.64.128.60:11000]

Не желая публиковать исходный код (я могу организовать, если потребуется, но необходимо будет удалить некоторые детали), код прослушивания сокета основан наэтот пример.

http://msdn.microsoft.com/en-us/library/5w7b7x5f.aspx

Любая помощь очень ценится.


Привет всем,

Спасибо за ваши ответы.

Я добавил больше журналирования и обработки исключений в функцию ReceiveCallback и обнаружил следующее в моем файле журнала сегодня утром ...

2011-05-25 04:52:26,816 [5] INFO  Uk.Co.RCID.MoteServer.Server.SocketListener [(null)] - Waiting for a connection...
2011-05-25 04:52:26,816 [10] INFO  Uk.Co.RCID.MoteServer.Server.SocketListener     [(null)] - Connection established on [10.64.128.60:11000]
2011-05-25 04:53:26,841 [10] WARN  Uk.Co.RCID.MoteServer.Server.SocketListener [(null)] - SocketException thrown in ReceiveCallback
2011-05-25 04:53:26,841 [10] WARN  Uk.Co.RCID.MoteServer.Server.SocketListener [(null)] - ErrorCode: [10054]
2011-05-25 04:53:26,841 [10] WARN  Uk.Co.RCID.MoteServer.Server.SocketListener [(null)] - System.Net.Sockets.SocketException (0x80004005): An existing connection was forcibly closed by the remote host at System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult) at Uk.Co.RCID.MoteServer.Server.SocketListener.ReceiveCallback(IAsyncResult ar)

Итак, ключ (как выделено в некоторых ответах выше)поймать исключения внутри функции ReceiveCallback и решить, достаточно ли они серьезны, чтобы убить ваше приложение.

Ответы [ 4 ]

2 голосов
/ 24 мая 2011

Если ваш код следует примеру очень близко, тогда вам действительно нужно попробовать:

int read = handler.EndReceive(ar);

в функции ReceiveCallback, потому что это может быть что-то простоекак соединение сокета закрывается, пока вы пытаетесь получить.

Вместо того, чтобы убить процесс, вы можете просто продолжить.

2 голосов
/ 24 мая 2011

Вы должны всегда catch (Exception err) во всех методах обратного вызова. DO протоколировать исключение.

Причина в том, что все необработанные исключения, созданные в любом другом потоке, кроме основного потока, прекратят работу вашего приложения.

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

0 голосов
/ 24 мая 2011

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

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

0 голосов
/ 24 мая 2011

Первое, что я хотел бы сделать, это проверить значение свойства ErrorCode в брошенном SocketException.Найдите это значение в списке кодов ошибок winsock , чтобы найти указатели на то, что может быть не так.

Если вы отправите код ошибки, я смогу помочь в дальнейшем.*

...