Open GoogleCodeExporter opened 8 years ago
The purpose of the method CatchExceptionAndRemoveMasterEndPoint is to catch
exceptions that we can expect to occur during normal operation and handle them
accordingly. For example, it is possible for a master slave TCP connection to be
closed during the middle of any message exchange (e.g. client is closed). When
this
happens an IOException is thrown with a specific inner SocketException. We
check for
this special case and handle it gracefully.
Although catching all exceptions as you proposed will prevent the slave from
crashing, it will also mask legitimate bugs.
In short, if the ModbusTcpSlave crashes it is a bug should be fixed.
Scott
Original comment by sja...@gmail.com
on 29 May 2008 at 9:56
You are of cause correct, but any call to CatchExceptionAndRemoveMasterEndPoint
should be encapsulated in a try catch block in that case.
Regards,
/ F
Original comment by fredrik....@isg.se
on 29 May 2008 at 10:07
I'm not sure you're getting me. I'm already handling the exceptions I know
about, if
any other unexpected exceptions occur I /want/ the slave to crash (then the bug
should be fixed). Therefore I do /not/ want to additionally wrap calls to
CatchExceptionAndRemoveMasterEndPoint in a try catch block.
Scott
Original comment by sja...@gmail.com
on 29 May 2008 at 10:12
I will try to send you a stack trace when the error occurs. It is super simple
to
get the error. Simply unplug the master from the network during
communication....
/ Fredrik
Original comment by fredrik....@isg.se
on 29 May 2008 at 10:22
That would be great if you could send a stack trace. This is exactly the kind
of bug
we don't want :)
Scott
Original comment by sja...@gmail.com
on 29 May 2008 at 10:24
No more response here...
Original comment by sja...@gmail.com
on 24 Nov 2008 at 2:47
Just did a new project with NModbus. If a master is disconnectet by means of
for example pulling out a network cable, slave crashes.
See stack trace. As you can see it is not a call initiated by user code, and
therefore the exception cannot be taken care of.
ERROR Got unexpected exception: Unable to read data from the transport
connection: A connection attempt failed because the connected party did not
properly respond after a period of time, or established connection failed
because connected host has failed to respond.
StackTrace: at System.Net.Sockets.NetworkStream.EndRead(IAsyncResult
asyncResult)
at Modbus.Device.ModbusMasterTcpConnection.<>c__DisplayClass1.<ReadHeaderCompleted>b__0()
at Modbus.Device.ModbusMasterTcpConnection.CatchExceptionAndRemoveMasterEndPoint(Action action, String endPoint)
at Modbus.Device.ModbusMasterTcpConnection.ReadHeaderCompleted(IAsyncResult ar)
at System.Net.LazyAsyncResult.Complete(IntPtr userToken)
at System.Net.ContextAwareResult.CompleteCallback(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Net.ContextAwareResult.Complete(IntPtr userToken)
at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken)
at System.Net.Sockets.BaseOverlappedAsyncResult.CompletionPortCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
Original comment by fredrik....@isg.se
on 4 Nov 2011 at 10:18
Reopening the issue since there is added information.
Original comment by jke...@gmail.com
on 10 Nov 2011 at 12:59
I am having the same problem with CatchExceptionAndRemoveMasterEndPoint.
Assuming that I have understood the code correctly this method is executed in
asynchronous callbacks only.
When you re-throw the exceptions this crashes the application.
I have a master device that uses modbus RTU over Ethernet i.e. it sends
complete RTU packets using TCP as the transport; not Modbus/TCP packets.
I have successfully got it working by developing my own adapter for this.
I have discovered that when I use a standard Modbus/TCP slave (which my
application must also support) the slave crashes my program when I send
telegrams from this master.
The fault occurs in ReadFrameCompleted when
ModbusMessageFactory.CreateModbusRequest throws a FormatException (which is
expected as the packet format is incorrect).
This is captured by CatchExceptionAndRemoveMasterEndPoint but the master is not
removed as this exception is not explicitly handled.
I think that because the method is executed in an asynchronous callback thread
the re-throw of this exception causes the program to crash!
I am using NModus v1.11 (re-built for .net 4 cp but no other changes)
Application is built using VS2010 C# .
Any advice on how to best prevent this error would be welcome.
Nick
Original comment by nick.cr...@nov.com
on 17 Jul 2012 at 12:59
Has anyone found a fix or workaround for this problem?
Klaus
Original comment by k...@it-gmbh.de
on 7 Aug 2012 at 5:21
I tried to fix the problem by the following change to
ModbusMasterTcpConnection.ReadFrameCompleted:
internal void ReadFrameCompleted(IAsyncResult ar)
{
CatchExceptionAndRemoveMasterEndPoint(() =>
{
// BEGIN CHANGE
int bytesRead = Stream.EndRead(ar);
_log.DebugFormat("Read Frame completed {0} bytes", bytesRead);
if (bytesRead == 0)
{
_log.Debug("0 bytes read, Master has closed Socket connection.");
EventHandler<TcpConnectionEventArgs> handler = ModbusMasterTcpConnectionClosed;
if (handler != null)
handler(this, new TcpConnectionEventArgs(EndPoint));
return;
}
// END CHANGE
byte[] frame = CollectionUtility.Concat(_mbapHeader, _messageFrame);
_log.InfoFormat("RX: {0}", StringUtility.Join(", ", frame));
// ...
I seems to work, but I'm not sure it is the correct solution
Klaus
Original comment by k...@it-gmbh.de
on 10 Aug 2012 at 11:43
Perhaps in the mind of the creator, the right solution may be :
internal void CatchExceptionAndRemoveMasterEndPoint(Action action, string endPoint)
{
// ......
catch (IOException ioe)
{
_log.DebugFormat("IOException encountered in ReadHeaderCompleted - {0}", ioe.Message);
ModbusMasterTcpConnectionClosed.Raise(this, new TcpConnectionEventArgs(EndPoint));
SocketException socketException = ioe.InnerException as SocketException;
if (socketException != null && socketException.ErrorCode == Modbus.ConnectionResetByPeer)
{
_log.Debug("Socket Exception ConnectionResetByPeer, Master closed connection.");
return;
}
//declare "public const int ConnectionAborted = 10053;" in Modbus.cs !!!
if (socketException != null && socketException.ErrorCode == Modbus.ConnectionAborted)
{
_log.Debug("Socket Exception ConnectionAborted, Master closed connection.");
return;
}
_log.Error("Unexpected IOException encountered", ioe);
throw;
}
//...........
// Take care to define:
// public const int ConnectionAborted = 10053;
// in Modbus.cs
Btw in my code i use a stronger approach handling ALL IOException disconnecting
the master and going on silently.
Regards
nik
Original comment by nicola.p...@gmail.com
on 5 Apr 2014 at 9:20
Has anyone tested whether nik's solution above, works to fully address the
issue? We're having this problem with our code as well and haven't been able to
kill it. Or, nik, can you provide more information about the "stronger approach
handling ALL IOException" you mentioned?
Thank you,
Graeme
Original comment by graeme.h...@gmail.com
on 17 Mar 2015 at 4:40
We are experiencing same issue. Would be great to be able to handle all
exceptions without terminating host application.
Original comment by vicentem...@gmail.com
on 14 Jul 2015 at 4:04
Original issue reported on code.google.com by
fredrik....@isg.se
on 29 May 2008 at 9:34