LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Using UDP to send and receive messages to my application

I am using CVI LabWindows 2017. I am struggling to make my idea work. For now, I am not supplying any code, because I can write that once I understand what is happening or what I need to change to make my idea work. Here goes....I will describe the system in some detail and explain what I am attempting to do.

 

I have created and application in LabWindows that communicates with hardware via a USB to I2C connection using a FTDI chip. That all works great and is not giving me any problems. This application also spawns a TCP server at start up that will pass data and control messages to a LabView VI for being able to interface my application in the LabView environment. This also works as expected. The other thing that you need to know and where things start to get more complicated is when I run multiple instances of my application. I want to be able to run up to 8 instances, but I have only tried up to 4. It is my belief that on a relatively fast computer this should be no problem. Since each instance spawns a TCP server, I had to give my ethernet connection up to 8 static IP addresses to use so they would be able to communicate with a VI. As each instance starts, it consumes and IP address and is accounted for in software. Again, that has all been tested and worked as expected. Scaling up should not be a problem once I get to that point, at least that is my contention. Here comes the part when things start to get very hard.

 

All of this of course is happening on one computer. I need to have all of these 8 instances of my application work in unison, so I have started to develop another application in LabWindows that will communicate with the 8 instances of my other application. My thought is to use UDP to accomplish this. I also need it to be full-duplex. I have been able to communicate in half-duplex via UDP with the first application which I will call the host using the second application which I will call the Control Panel. This works great. I read where this UDP communications can be send and receive in the NI help file for UDP functions. While I have been testing my UDP code, I have had the TCP code disabled. I have concerns as to what will happen when I re-enable this code.

 

So this is the way I want communications to occur between the control panel and the host software. When the control panel starts it will launch the host software, wait a little while and then send a UDP message to find out if the host started properly by sending a message structure that the host will decode and then send back a message to the control panel that would tell the control panel that the host was indeed launched and can be communicated with. This is where I get to in my code. I can see using WireShark, all of these messages, but the control panel never sees the response. Once I get this to work, there will be other messages to and from these applications, but mainly the control panel will behave as a server and the hosts will behave as clients as I need to control them with the control panel, hence the name.

 

This is how I coded each of the applications. The code is nearly identical in each application. I created an openWrite function  where I used this function CreateUDPChannel (UDP_ANY_LOCAL_PORT, &writeChannel) and an openRead function where I used this function CreateUDPChannelConfig (DEFAULT_UDP_PORT, ipAddress, ZERO, CallbackCB, NULL, &readChannel) where the IP address was one of the static IP addresses, and were different on the control panel and the host application, I assigned to ipAddress one of the address from the pool assigned to the ethernet card and the CallbackCB was implemented per the NI specification. I limited this to just one launch of the host application just to keep everything simple. I also coded the callback to process the data received using the UDP read function and I wrote another function that did a UDP write function where it wrote the data to the broadcast UDP ip address of 228.0.1.1. This all seemed to be pretty straight forward. It worked except that when I sent the replay back to the control panel using the UDP ip address of 228.0.1.1 which the control panel was also subscribed to, I never got any notification in the callback function that processes the received data that any data was ever received. In other words, the breakpoint I placed in that callback function was never tripped, even though I saw the data being sent via UDP on address 228.0.1.1 on WireShark.

 

Hopefully you followed all that. Again, this is not so much how to write the code. I know how to do that. I am looking for confirmation that I am doing this implementation correctly or not, and if not what do I need to change. I know that a lot of things use UDP and it works for them. It should work for me also. I DO NOT think it should matter whether or not I do this on one computer or on separate computers, as this is all just based on IP addresses and I can assign multiple static IP addresses to my ethernet card. However, if UDP does not like this and prefers dynamic IP addresses then I need to know this. I am a newbie to how UDP works and what it takes to implement this protocol, but obviously I can read, I just have not found enough on how it works yet. Please inform me where I got this wrong, or better yet point me to some fully functioning full-duplex UDP code. I have followed and used the multiple examples in NI example folder for UDP, but those are all half-duplex examples.

 

Thanks for anything you can provide in making this work, as I am so close. I will post code if you ask for it. I will also clarify anything that doe not make sense or I forgot to tell you about. Again, thanks for your help.

0 Kudos
Message 1 of 3
(3,182 Views)

While I have been waiting for a reply to my post, I took a couple of the example projects that dealt with UDP and combined them, making a much simpler application to test out my ideas. I am happy to say that I got it to work. I am including my code so you can see what I accomplished. Here is how to make it work on one computer. For two computers on the same subnet, just run the code after changing the IP address to that computer. There are a few lines that do things and I have commented them out, just so you don't say why did that happen.

 

To make this work you will need 2 static IP addresses. change the IP address on lines 67 and 69 to one of the static IP addresses. Then build that code and rename the exe to something else. Now go back and change the lines 67 and 69 to the other IP address and compile to an exe. Now run both of the executables remembering which IP was assigned to which program. Now you can communicate using UDP in full-duplex and with the few lines that I commented out, you can have one or both programs do something depending upon what was sent to them. This could be modified in many ways to do just about anything.

 

BUT, while I was making this program I did find a bug. Well at least something did not work as expected. I will explain. Lines 65 and 66 are commented out because if you try to assign and IP address that way it appears to work, but does not. When you do a GetUDPAttribute() for ATTR_UDP_MULTICAST_OUTPUT_INTERFACE it reports that as the address you specified on line 66. That is not the address my program shows. It always seems to use the default IP address of the computer no mater what. However, if you use CreateUDPChannelConfig() to set the IP address, the correct address is reported by the program. I works OK, but the correct IP address is not being given to the callback function that gets the received data packets. I can demonstrate this if I need to show you. This caused some head scratching as knowing who sent the message will be very important in what I am trying to accomplish in my control panel.

 

Now if I can just get the TCP server to play nicely, I will have it. Here is the code.

0 Kudos
Message 2 of 3
(3,168 Views)

I will admit to not knowing anything about UDP, but I have done some similar work with TCP/IP in the past.  However, I recently had to satisfy a similar need for full-duplex communication between CVI applications.  To do this, I chose the native windows interprocess communications APIs known as named pipes.  See details HERE. 

 

This method uses simple WIN32 API calls that work almost identically to reading and writing from a disk file.  I can confirm that full-duplex communication is very fast and very stable for the data transfers that I am doing under windoze 10.  A quick duckduckgo search for "Interprocess Communication" should bring up a wealth of examples on how to get this method up and running.

0 Kudos
Message 3 of 3
(3,136 Views)