« DNP, Substation Automation and DA on LinkedIn | Main | Is DNP Protocol Networkable? »

So, is my TCP Socket connected or not?

Hello Again,

 

I have been absent for a while, I know. The truth is I was putting the final touch on our newest product: Modbus Plant Simulator. The idea is to have a tool to help the engineers to detect problems and issues with their SCADA, tag names, addressing, IO Server problems, etc before they deploy the system. I believe it would help a lot and save lots of money and time. Any way, if you like to see it for yourself, just download it from this address:

http://www.controltoolbox.com/modbus_tcp_plant_simulator

 

The issue I like to talk about is an apparent flaw in the way that the Sockets are handled in .Net 3.5. My problem was that I needed to know if a connection is closed without doing any real IO operation like Send or Receive. My sockets were defined as steam and were working in non-blocking mode.

 

Microsoft help document tells you to do the following (Socket.Connected Property):

// .Connect throws an exception if unsuccessful
client.Connect(anEndPoint);
// This is how you can determine whether a socket is still connected.
bool blockingState = client.Blocking;
try
{
    byte [] tmp = new byte[1];
    client.Blocking = false;
    client.Send(tmp, 0, 0);
    Console.WriteLine("Connected!");
}
catch (SocketException e)
{
    // 10035 == WSAEWOULDBLOCK
    if (e.NativeErrorCode.Equals(10035))
        Console.WriteLine("Still Connected, but the Send would block");
    else
    {
        Console.WriteLine("Disconnected: error code {0}!", e.NativeErrorCode);
    }
}
finally
{
    client.Blocking = blockingState;
}
 Console.WriteLine("Connected: {0}", client.Connected);

 

Basically it is telling you to call Send() with 0 bytes. The problem is it does not work. If you try to send any number of bytes more than 0, you get the intended results from the code. Of course you cannot send an arbitrary message on the line just to make sure the connection is still closed! What I ended up doing was to do Receive() in every pass. As mentioned before, my Socket was set in non-blocking mode. Interestingly, as long as the connection was there, I would get an exception every time I call the Receive() if there was nothing in the buffer. As soon as the connection goes down, I stop receiving the exceptions! The call returns normally with 0 received bytes!

 

May be there is somebody somewhere to have an explanation for this, but until we find that person you may want to do what I did to detect the status of the connection!

 

Take care for now, Rod.

 

TrackBack

TrackBack URL for this entry:
http://controltoolbox.com/blog-mt/mt-tb.fcgi/10


Hosting by Yahoo!