Jump to content

Check for data on TCP connection


Recommended Posts

Doesn't anyone know a solution to my problem? Or will this better get answered in some other forum like "application Design & Architecture" which has more visits?

Br, Miha

OK. I'll get serious (just for a moment biggrin.gif). It depends on what you are trying to do.

As far as I'm aware (under windows at least) there is no native labview way to "hook" a TCPIP connection. In fact, without a kernel level driver not many other apps can either (they use WinPCap). I know RolfK did a load with TCPIP which got into the nuts and bolts of TCPIP and UDP (they're on LAVA somewhere). But I only looked at them briefly - maybe something in there for you.

If you just want to detect if something is active, you can ,however, just open the port. If it fails; "something" has it. Quick and dirty if that's all you need to know.

The other way is as a proxy handler. Where, each end-point connects to ports in your software so you become the "man-in-the-middle". you can then pretty much do what you like with the streams form that point but you stipulate "without reading" so I guess that's out.

Labview tries to alleviate the programmer from really low level stuff, so it's not surprising there is nothing "off-the-shelf". You are probably better off using wire-shark, logging to a file, then reading it in LV (I don't know if Wire-shark has an API or not).

Link to comment

Ok, I see that I will have to elaborate. I mistakenly thought my question was clear enough.

I have actually a TCP connection open in LabView, but I would not like to read from it, I would like to call some VI that would block (with the timeout set by me) until data is available. Then I will call another VI that will actually read from the connection and do something with the data.

Or to be specific - I am using STM, but STM only has one parameter. The timeout can be set when reading a message, but unfortunately this timeout isn't used only when waiting for the data. It also seems to be used internally. The effect is, that if I set the STM timeout too short (lets say 100ms), then STM stops working because the timeout is too short to compose the entire message. So the timeout needs to be larger, about 1000ms. But I don't want to wait for 1 second for a new message. I want to wait for it just for 100ms. If it arrives, I will read it, if not, I will do other things.

And since I don't want to modify the STM library and break compatibility with NI, I decided to look for some other function that would wait for new data without removing it from the connection. If the data comes, then STM will be used with its default settings to read the message.

I hope my intention is clearer now.

Thank you for any pointers, Mike

Edited by mike5
Link to comment

There is no LabVIEW function that will do this. You can only determine if data is available on a connection by reading it. What you may want to do is move the STM calls into a separate loop and put the data that you read into a queue, where you'll have more control over it. You may also want to enqueue the connection info along with the data in case you need to send a response to the same connection. I've done this in the past with variants - one loop reads the TCP data, turns into into a variant, adds the connection ID as an attribute, then enqueues it. Another loop dequeues the data, processes it, reads the connection ID attribute and copies that to a new variant containing the response data, and enqueues it so that the send/receive loop can dequeue it and send it along.

Link to comment

Ok, I see that I will have to elaborate. I mistakenly thought my question was clear enough.

I have actually a TCP connection open in LabView, but I would not like to read from it, I would like to call some VI that would block (with the timeout set by me) until data is available. Then I will call another VI that will actually read from the connection and do something with the data.

Or to be specific - I am using STM, but STM only has one parameter. The timeout can be set when reading a message, but unfortunately this timeout isn't used only when waiting for the data. It also seems to be used internally. The effect is, that if I set the STM timeout too short (lets say 100ms), then STM stops working because the timeout is too short to compose the entire message. So the timeout needs to be larger, about 1000ms. But I don't want to wait for 1 second for a new message. I want to wait for it just for 100ms. If it arrives, I will read it, if not, I will do other things.

And since I don't want to modify the STM library and break compatibility with NI, I decided to look for some other function that would wait for new data without removing it from the connection. If the data comes, then STM will be used with its default settings to read the message.

I hope my intention is clearer now.

Thank you for any pointers, Mike

Ned's suggestion is very good and a great way to handle this. If that doesn't meet your needs you could also check to see if data is available by reading a single byte of data using a short timeout. If no data is there then move on and do other things. If data is present then go to your read state and read more data. In that state you could use a longer timeout as well as look for whatever termination character you use. Your state machine would have to periodically check to see if data were available. However, it sounds like you will read the data if there is some so the single byte read would be one way of checking if data is there before doing more processing. Naturally you would have to buffer the byte you read so it will be processed with the other data.

Link to comment

Ok, I see that I will have to elaborate. I mistakenly thought my question was clear enough.

I have actually a TCP connection open in LabView, but I would not like to read from it, I would like to call some VI that would block (with the timeout set by me) until data is available. Then I will call another VI that will actually read from the connection and do something with the data.

Or to be specific - I am using STM, but STM only has one parameter. The timeout can be set when reading a message, but unfortunately this timeout isn't used only when waiting for the data. It also seems to be used internally. The effect is, that if I set the STM timeout too short (lets say 100ms), then STM stops working because the timeout is too short to compose the entire message. So the timeout needs to be larger, about 1000ms. But I don't want to wait for 1 second for a new message. I want to wait for it just for 100ms. If it arrives, I will read it, if not, I will do other things.

And since I don't want to modify the STM library and break compatibility with NI, I decided to look for some other function that would wait for new data without removing it from the connection. If the data comes, then STM will be used with its default settings to read the message.

I hope my intention is clearer now.

Thank you for any pointers, Mike

If you set your TCPIP read function to "IMMEDIATE". IT will wait for the time-out period if nothing is received and return immediately if some bytes arrive.

Alternatively. If you open your TCPIP connection using the VISA functions instead of the TCPIP functions; you can you can then use a property node to read the number of bytes at the port before reading. It will also enable you (if I remember correctly) to set different time-outs for the read and write functions.

If you are using a native labview STM driver, you can always go in and hard-wire the time-outs manually.

Link to comment

You can probably use the socket handle to see if data exists on the connection - you can get the OS socket handle with the vi.lib\Utility\tcp.llb\TCP Get Raw Net Object.vi. Then use that socket handle and call the winsock recv() with the MSG_PEEK flag (assuming you're on windows). This might work to tell you if a TCP connection created thru the LabVIEW function has data available.

Mark

Link to comment

You can probably use the socket handle to see if data exists on the connection - you can get the OS socket handle with the vi.lib\Utility\tcp.llb\TCP Get Raw Net Object.vi. Then use that socket handle and call the winsock recv() with the MSG_PEEK flag (assuming you're on windows). This might work to tell you if a TCP connection created thru the LabVIEW function has data available.

Mark

Thanks! That sounds like a good plan.

Br, Mike

Link to comment

You can probably use the socket handle to see if data exists on the connection - you can get the OS socket handle with the vi.lib\Utility\tcp.llb\TCP Get Raw Net Object.vi. Then use that socket handle and call the winsock recv() with the MSG_PEEK flag (assuming you're on windows). This might work to tell you if a TCP connection created thru the LabVIEW function has data available.

Mark

I tried to make this work, but I always get error 1097 when calling recv. Did anyone manage to get this working? Here's my VI, if you want to try it yourself and maybe spot an error.

Thanks and br, Mike

Peek Raw Socket.vi

Edited by mike5
Link to comment
  • 2 weeks later...

I know RolfK did a load with TCPIP which got into the nuts and bolts of TCPIP and UDP (they're on LAVA somewhere). But I only looked at them briefly - maybe something in there for you.

No my library wouldn't really help with that although it could probably add such a poll feature somehow. The library really is meant to make use of SSL and other TCP/IP socket functionality almost as simply as the original TCP nodes do. For IPv6 that is already mostly there, ping also with the additional limit of the required administrative rights, that is basically impossible to avoid on most modern OSes.

SSL is another issue. SSL supports a lot of different kinds of operations and parameters that all need to be somehow supported. However most of them are obscure, with no examples at all and often seldom used. So for the time being the library supports opening SSL sockets with default settings, but not yet custom certificates and other stuff such as authentication since that requires a way to enter parameters when creating the socket. I have some ideas how to allow doing that but that requires quite some infrastructure and then the chances that anybody is going to use it are still very small.

My library doesn't currently support accessing native TCP refnums other than a somewhat hidden feature with separate Get and Set Attribute VIs that can access any of the supported socket attributes also on native TCP and UDP refnums. Unfortunately there is no way of supporting that through the publicly exposed property nodes itself but only through the special VIs, which is not as convenient as the property nodes.

Win 7 x64 LV2010 x64.

Change the socket parameter to a "pointer sized integer". it wont work if you are using lv x32 with a u64

Just one more comment. The error handling with WSAGetLastError() is probably never gonna return a meaningful error. (WSA)GetLastError() retrieves a thread local storage value set previously by another function. That assumes that the previous function and GetLastError() are called in the same thread and without any other function in between that could set that value. Since the CLN's are set to execute in any thread this is absolutely impossible to guarantee and in my experience actually almost never happens either.

Not even setting both CLNs to execute in the UI execution system would be able to guarantee proper operation, since theoretically there could still execute another call to an API that influences this value, between when LabVIEW calls the recv() function and when it eventually calls the WSAGetLastError().

The only way to guarantee that this is working properly is by locating both calls in an external call library in one single function and call that through a CLN.

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.