Jump to content

TCP Write works when it shouldn't


Recommended Posts

Hi all,

 

I have a strange little problem.  I have two computers talking to each other via TCP (thru a router).  Computer A sends out a short (1200-ish bytes) message via TCP Write.vi and Computer B responds with a different short message.  This happens every 10 seconds.

 

Here's the strange part...  If I disconnect the network cable from Computer A during the 10 second wait, the TCP Write from Computer A still "completes" without an error even though there is no physical connection to the network when the function executes.  It's not until Computer A tries to read the response from Computer B (via TCP Read.vi) that it errors out (with error 66, which is another problem).

 

This lead me to believe there was buffering going on with the write and it just didn't know there wasn't anything out there to talk to anymore.  So, I tried disabling the Nagle algorithm (both manually via the registry and then using TCP_NoDelay.vi) but this seemed to have no affect. 

 

Any comments on what I'm seeing?  If this is buffering, is there any other way of forcing the TCP Write to actually write (and hopefully throw an error)?

 

Cat

Edited by Cat
Link to comment

Unfortunately I think you're out of luck. This is the expected behavior - LabVIEW's TCP Write hands the data off to the operating system, and then is done with it. Depending on the network configuration, it could potentially take a very long time for the data to be delivered, and you wouldn't want your LabVIEW code blocked that whole time. There are probably situations in which you could unplug the network cable, then plug it back in again and have the data sent successfully. I haven't experimented with this but the operating system may not close all connections the moment that the network cable is disconnected - there could be some delay in case the network is restored quickly. You could try adding a TCP Read for 0 bytes immediately after the write, but I don't know if it will reliably detect if the connection is broken.

Link to comment

You are correct -- after Computer A is disconnected, and the TCP Write executes with no error, if I plug the network cable back in again within a few seconds, Computer B sends the response and Computer A receives it correctly.

 

I tried the 0 byte TCP Read after the write, but it did not throw an error.  Thanks for the suggestion, though.

 

Cat

Link to comment

You are correct -- after Computer A is disconnected, and the TCP Write executes with no error, if I plug the network cable back in again within a few seconds, Computer B sends the response and Computer A receives it correctly.

 

I tried the 0 byte TCP Read after the write, but it did not throw an error.  Thanks for the suggestion, though.

 

Cat

 

TCP/IP was specifically designed to be robust. This means that the protocol can handle disruptions of a connection and retransmission of data over the same connection or even an alternative connection route. So what you see is not a bug but you simply have different expectations than what is the reality. TCP/IP eventually has timeouts that will terminate a connection, if after some amount of retransmissions no ack or sync was received, but those timeouts are in the range of 10s of seconds. Once the connection has been put in one of the FIN_WAIT, CLOSE_WAIT or CLOSING states even the TCP Write will return with an error but not before.

 

Here is a short introduction into TCP/IP operation and why this reliability can indeed pose some surprises for the unexpecting.  

Link to comment

You need to use "GetIpAddrTable" and then look at wType to see if it is MIB_IPADDR_DISCONNECTED.

 

This just reminded me........

I was making fun of my Linux fanatic friend. I said you can tell the difference between a Windows and Linux programmer by how they approach a task.

 

If the task is to tell if you are connected to a network.

 

The windows programmer will call an API function to find out the network card state.

A Linux programmer will monitor the LED blinking on the network card with a webcam, pipe it to a file then regex the file to see if the LED is on :D

 

He scowled. Thought about it and then said, with a smile,. "Nope. We'd get an intern to watch the LED and SMS us on the yacht when it changes" - Touche!.

Edited by ShaunR
  • Like 2
Link to comment

[...] you simply have different expectations than what is the reality.

 

This very succinctly sums up the reason for most of my problems in life.  :P

 

Thanks for the link, it was very interesting.

 

So it sounds like even tho I'm setting TCP_NODELAY, and (assuming it's working) the message is being sent out immediately, thanks to the TCP protocol, it's still getting stuck in the system regardless of whether or not there's a physical connection anymore.

 

What if I sent the message via UDP -- would it error out faster?  Not that that's really an option with the current system, but I'm just curious.

Link to comment

This very succinctly sums up the reason for most of my problems in life.  :P

 

Thanks for the link, it was very interesting.

 

So it sounds like even tho I'm setting TCP_NODELAY, and (assuming it's working) the message is being sent out immediately, thanks to the TCP protocol, it's still getting stuck in the system regardless of whether or not there's a physical connection anymore.

 

What if I sent the message via UDP -- would it error out faster?  Not that that's really an option with the current system, but I'm just curious.

 

TCP_NODELAY doesn't change anything about the underlaying TCP/IP protocol. It disables a feature of the socket that prevents the connection to cause to send a new Ethernet packet for every little data blurb a program might cause. Since the Ethernet TCP/IP protocol consists of multiple layered data packets each with its own header, an application trying to send a message byte by byte would badly congest the network if the Naggle algorithme wasn't there. And that is not an academic idea. The Naggle algorithme wasn't added because of an academic idea that presented a problem that didn't exist for real! :D

 

But that algorithme is a limiting factor for command-response protocols that want to have more than 2-3 roundtrips per second. Now you can argue that such a protocol is actually very unsuited for the realities for interconnected internet, where the response time as reported by a simple ping easily can be in the 100ds of milliseconds. But if you want to do communication on a local network it can be helpful to be able to disable the Naggle algorithme.

 

As to if UDP would help: I don't think so. UDP hasn't even a concept of acknowledgement of transmitted data. So it is even more according to the principle: blast it out and forget and don't ever care about who received it, and if any.

 

The socket interface itself has traditionally no way to check the actual status of the network cable. Under Unix flavors there are some extensions available that allow to get the status of an interface node through the socket interface (but not through the actual socket of a connection). And those extensions can be quite different between Unix flavors and even between distributions of Linux alone. Under Windows this has to be done using the iphlp.dll, Winsock doesn't expose an API to query the interface nodes but only inplements the normal Berkeley socket API to handle connections/sockets.

Link to comment

You need to use "GetIpAddrTable" and then look at wType to see if it is MIB_IPADDR_DISCONNECTED.

 

Gak!  You're making me read C.  I hate it when you do that!  :angry:  :lol:

 

Very funny joke, BTW.  I certainly haven't bothered to ask the Linux guys (Computer B) what's happening on their side during all of this.  :rolleyes:

Link to comment

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.