Well, I thought I knew all there is to know about TCP connections - I’ve been using them for years, but I have found a new wrinkle.
I’m using a pattern I’ve used before, except this time I’m trying to automatically re-establish a broken connection:
ConnID = NaN
repeat
if ConnID = NaN // if there is no connection...
ConnID = TCP OPEN CONNECTION (Address, Port, Timeout = 1000)
if ConnID = NaN // could not connect
Flag = FALSE // make sure light is off
else
Issue CONNECT event (Conn ID) // internal event
CONNECTED LIGHT. ObjHighlight ( ); // draw attention to the change in status
Flag = TRUE // make sure light is on
end if
else
Command = RECEIVE MESSAGE (Conn ID, Timeout = Infinite)
if Command = Disconnect
Issue DISCONNECT event // internal event
* Wait (N) mSec
ConnID = NaN
Flag = FALSE
else
Handle other command
Flag = TRUE
end if
end if
CONNECTED LIGHT = FLAG
while RUNNING = TRUE
The *WAIT was inserted just for purposes of this question.
The basic logic is :
If there is no connection
Try for 1000 mSec to make one
else
Receive messages
end if
The pattern worked fine, without the ObjHighlight( ), for quite a while.
I decided I wanted to draw user attention to the fact that the connection was made, so I inserted the ObjHighlight( ) where the connection was first made.
That works fine. Regardless of whether the host (this code) or the other end starts first, this code makes the connection, and now highlights the light when connecting.
But what I don’t understand is that the highlight ALSO happens when the other end BREAKS the connection.
If I kill the other end, then the light highlights, and then is OFF.
I have verified that there is one and only one ObjHighlight( ) node, and that it is indeed where I have listed it above. A breakpoint verifies that it is indeed called when the connection is BROKEN.
The RECEIVE MESSAGE subVI waits on a message on the given ConnID, and turns an error into a DISCONNECT command. It also sets the ConnID to NaN, in case of error.
So, this means that, when the other end breaks:
— The RECEIVE MESSAGE subVI sees the break, quits waiting, and reports a DISCONNECT command
— The DISCONNECT command turns off the light.
— The loop cycles
— We try to connect again
— We SUCCEED in connecting again ( why? )
— We highlight the light and turn it on, because we connected.
— We try to receive
— We fail, with a DISCONNECT command
— We turn off the light.
What I don’t understand is why the re-try succeeds. I break the other end by ABORTing the program that is running (on the PXI).
So, how is it that a stopped program can allow a new connection?
Now if I use the WAIT function with N = 0..125, nothing changes.
But if N = 150 or more, it does not exhibit this behavior. The light does NOT highlight when the connection is broken.
I can infer from that, that the system on the other end hasn’t fully reacted to the ABORT and still has the “ringer turned on” so that it can still hear an incoming call.
Somewhere between 125 and 150 mSec, it gets around to shutting off the ringer and all behaves as expected.
Oddly enough, if i insert an ObjHighlight( ) call in the DISCONNECT case, that serves to delay things enough to where it works right, but I don't want to depend on that.
--------------------
So, is this a bug in the PXI’s OpSys? Or just a natural consequence of the fact that it cannot do everything at once? Or is there something I’m missing?
I don’t mind highlighting the light on connection breakage; it’s the extra CONNECT/DISCONNECT events that I want to avoid.
And if I have to wait a while, how long do I have to wait? Is the 150 mSec a property of this particular model (PXI-8196), or LVRT2013, or what?