Jump to content

Monitoring a TCP connection


Recommended Posts

Hello folks,

I have a VI that monitors a TCP connection using the function "Not a Number/Path/Refnum". When the peer (the other side which this VI is connected is a win program in Visual Basic) closes the connection, my VI seems unable to detect the closed connection, it is "thinking" that

the TCP refnum is still valid.

How I can handle it?

Thanks!

Link to post

QUOTE (Giseli Ramos @ May 19 2008, 07:32 AM)

I have a VI that monitors a TCP connection using the function "Not a Number/Path/Refnum". When the peer (the other side which this VI is connected is a win program in Visual Basic) closes the connection, my VI seems unable to detect the closed connection, it is "thinking" that

the TCP refnum is still valid.

How I can handle it?

You cannot use that function that way. Instead you need to check the error output from TCP Read or TCP Write. You will probably need to filter the errors, because some errors do not indicate a dropped connection (for example, TCP Read may return a timeout error because no data available, but the connection is still valid).

Link to post

QUOTE (ned @ May 19 2008, 09:03 AM)

You cannot use that function that way. Instead you need to check the error output from TCP Read or TCP Write. You will probably need to filter the errors, because some errors do not indicate a dropped connection (for example, TCP Read may return a timeout error because no data available, but the connection is still valid).

Well, so you say that I write/read to a tcp connection in time to time...

May be a dumb question, but for which specific things the "Not a Refnum" is made? Only to know when don't use it.

Anyway, thanks for the feedback, ned.

Link to post

QUOTE (Giseli Ramos @ May 19 2008, 09:17 AM)

May be a dumb question, but for which specific things the "Not a Refnum" is made? Only to know when don't use it.

Just because a refun exists, doesn't mean that the data associated with that refnum is valid. "refnum" is quite literally "reference number" - it's a reference to the software component instance that you're using, so in this case, it's the software layer of the TCP/IP engine - it has nothing to do with the actual connection. The connection uses the refnum, but the refnum does not use the connection.

I'm pretty sure I didn't explain that well - anyone else care to clarify my muddy thoughts?

Link to post

QUOTE (crelf @ May 19 2008, 05:45 AM)

The refnum is like a lifetime ticket to an amusement park. You can come & go (read & write) as you please, but if they close the park down (close the connection) you won't know about it until the next time you visit. Your ticket (refnum) still looks the same as it did before (same address, same promises of happiness, same terrifying mouse character) but trying to visit the park (read & write) causes errors (and disappointment).

What's more, it may be necessary to inspect the error information ("You are not allowed to enter the park because...") at a deeper level to determine why the error occurred (too many people in the park right now / you are not the right ticket holder / the park is closed forever / etc.).

Is that a tortured enough analogy?

QUOTE (Giseli Ramos @ May 19 2008, 05:17 AM)

May be a dumb question, but for which specific things the "Not a Refnum" is made? Only to know when don't use it.

<Not a Refnum> is what you would get if you went to your city's (Operating System's) ticket booth (Open TCP Connection) and said, "I wish to buy a ticket to Giseli's Super Fun Center," if that particular park didn't exist. Your ticket agent (Operating System) would say, "There is no amusement park by that name," (error) and would give you back... nothing (<Not a Refnum>). That's just one example.

There might be situations where you want to check whether a refnum is valid before reading/writing (to prevent errors before they happen rather than just detecting them after they happen). That's when you would use Not a Refnum?.

Link to post

QUOTE (Justin Goeres @ May 19 2008, 11:19 AM)

The refnum is like a lifetime ticket to an amusement park. You can come & go (read & write) as you please, but if they close the park down (close the connection) you won't know about it until the next time you visit. Your ticket (refnum) still looks the same as it did before (same address, same promises of happiness, same terrifying mouse character) but trying to visit the park (read & write) causes errors (and disappointment).

What's more, it may be necessary to inspect the error information ("You are not allowed to enter the park because...") at a deeper level to determine why the error occurred (too many people in the park right now / you are not the right ticket holder / the park is closed forever / etc.).

Is that a tortured enough analogy?

Whoa! That were a nice explanation! I understood it better... Thanks! Now I'm looking now for alternative (and right) ways to monitor a TCP connection.

I think that writing in time to time and see if occurs any errors is a reliable way. What do you think?

Link to post

QUOTE (crelf @ May 19 2008, 09:45 AM)

The connection uses the refnum, but the refnum does not use the connection.

Whoa, man, that's deep. :blink:

I agree, Justin's explanation is much nicer. He uses his tongue awful pertie.

Seriously, though... an old-time method for determining if a TCP connection is valid is to simply send a periodic small-sized message through the channel on a known, repeatable time basis. If for some reason the "heartbeat" isn't seen for longer than the selected timeout period, assume the connection has been lost, and take appropriate actions to re-establish the channel. I've used this to get around LV's somewhat hard-to-predict and occasionally inconsistent error-handling functions, which return different errors, for example, when you unplug an Ethernet cable vs. when you shut down power on a peer.

Link to post

QUOTE (BobHamburger @ May 19 2008, 08:43 PM)

I've used this to get around LV's somewhat hard-to-predict and occasionally inconsistent error-handling functions, which return different errors, for example, when you unplug an Ethernet cable vs. when you shut down power on a peer.

I think I know what you're talking about, and it's not inconsistent because it has its logic - when you disconnect the cable, the OS kills the network connection so that LabVIEW doesn't see the adapter any more. This would cause it to throw a different error.

Link to post

QUOTE (Yen @ May 19 2008, 01:12 PM)

Indeed. LabVIEW here only checks the OS error after doing socket calls and translates that error into it's own error number. And it was decided that a more granular error reporting is the good thing to do and I agree with it.

Another angle might be that the OP is not really interested into the actual connection at all but rather into the information if the network node is reachable at all. This is solved easily with a network ping as described in following http://forums.ni.com/ni/board/message?board.id=170&thread.id=70801&view=by_date_ascending&page=1' target="_blank">link.

I include a copy of the fixed version of that library. There is however one principal problem with LabVIEW's multithreading and the error reporting as done with sockets:

The WSA error is maintained on a thread specific global variable and for the blocking call when waiting on an answer from the remote node and in case of parallel execution of this utility in general this causes a small issue. So for this select call the reported error in case of a failure never will be the real error since the select call happens in one of the threads inside a multi threaded execution systems while the error retrieval will occur in the UI thread. Also if you run multiple ping calls in parallel, the error from one call may get overwritten by the execution of another call before the first VI had a chance to retrieve it's associated error.

The only real fix for this would be to write a wrapper DLL that does the actual socket call and error retrieval together in one function per different socket call (since the actual call to an external code routine is guranteed by LabVIEW to be atomic in terms of the actual calling thread inside LabVIEW.

I would like to add that the VIs are LabVIEW 7.0 and the original code is from m3nth on the NI forums.

Rolf Kalbermatter

Link to post

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.