UDP two-way communication

3,648 views
Skip to first unread message

Jon Ove

unread,
Feb 23, 2015, 8:55:52 AM2/23/15
to node...@googlegroups.com
Hi,

I am trying to communicate with an embedded device over UDP. I send UDP packets to a spescific port (port in node-red), and the device answers back on the sender port (outport in node-red). The problem is that if I bind the udp out node to a local port, this port is occupied and I cannot use a UDP in node to listen on this port.
Is there a way to get this to work, or is UDP two-way communication impossible in node-red?

Thanks for your help!

Best Regards,
Jon Ove

Dave C-J

unread,
Feb 23, 2015, 10:52:07 AM2/23/15
to node...@googlegroups.com
For the outbound port can you use the bind to a random port option ? that way it shouldn't be occupied, so the inbound port can specify what it wants.

Jon Ove Storhaug

unread,
Feb 23, 2015, 11:29:39 AM2/23/15
to node...@googlegroups.com

Thanks for your reply!
If I use random port, my embedded device will send the reply to the random port, and I will not receive it. So that will unfortnately not help me.

23. feb. 2015 16:52 skrev "Dave C-J" <dce...@gmail.com>:
For the outbound port can you use the bind to a random port option ? that way it shouldn't be occupied, so the inbound port can specify what it wants.

--
http://nodered.org
---
You received this message because you are subscribed to a topic in the Google Groups "Node-RED" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/node-red/dnN-ht14M48/unsubscribe.
To unsubscribe from this group and all its topics, send an email to node-red+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Dave C-J

unread,
Feb 23, 2015, 12:07:34 PM2/23/15
to node...@googlegroups.com
hmmm - that sounds like a bug.... should send to the destination port - the local port should be able to be random - will look.

Dave C-J

unread,
Feb 23, 2015, 2:21:14 PM2/23/15
to node...@googlegroups.com
Jon,

looking at the code - there should be a line in the console on startup saying something like
in the case of random port
    udp ready : 192.168.1.11:9999
in the case of fixed port (local = 8888)
    udp ready : 8888 -> 192.168.1.11:9999
we use the either the destination port or msg.port property of the incoming message (if the destination port is not configured) in order to send the message - it should never use the random port. 

Eg here is a wireshark capture
no    Time                 Source           SPort        Destination      DPort      
73 18.342301 192.168.1.131 8888 192.168.1.11 9999 UDP 55 Source port: ddi-udp-1  Destination port: distinct

So I think it's working Ok...


Jon Ove

unread,
Feb 24, 2015, 6:44:02 AM2/24/15
to node...@googlegroups.com
Hi,
Thanks for your help!
I am not sure if I was clear enough in my explanation of my problem. I don't think there is a bug in the node. I guess it is more the way it is designed.
When I send a UDP packet with random source port from node-red to my embedded device, this packet has this information:
Source           SPort        Destination      DPort      
noderedPC 59581 embedded dev  4002 UDP

My embedded device will then answer like this:
Source               SPort        Destination        DPort      
embedded dev   4002 noderedPC  59581   UDP

I guess that is normal behavior on both sides?

The problem is that I cannot (as far as I know) set node-red to listen on the same port as the source port of the sent message (59581). It will not help if I set port 4002 as source port and listening port. Then this port is occopied by the sender node. I think the solution would be to let the two nodes use the same bound port, and not let each node bind to its own port. But I guess this would mean a lot of redesigning. Do you understand what I mean?
I guess that more people than me has encountered this issue when trying to communicate two-ways with a UDP device. Is there a way to get around it? Has I missed something?

Thanks for your effort trying to help me!

Best Regards,
Jon Ove    


Dave C-J

unread,
Feb 24, 2015, 8:09:33 AM2/24/15
to node...@googlegroups.com
Hi Jon

 the following flow works for me... - the far end sends from a particular port there to me on a fixed port (9999)  and I reply back to the originating port at the far end.... It is up to the far end to set it's sending port that I will reply to.

[{"id":"140c03.ffebf3fd","type":"udp in","name":"","iface":"","port":"9999","datatype":"utf8","multicast":"false","group":"","x":178,"y":520,"z":"6b5c7d92.94a384","wires":[["a457f763.5ba808"]]},{"id":"a457f763.5ba808","type":"function","name":"","func":"msg.payload = \"You said : \"+msg.payload;\nreturn msg;","outputs":1,"valid":true,"x":408,"y":503,"z":"6b5c7d92.94a384","wires":[["b64e2156.49b1e","65fc2e61.9a03d"]]},{"id":"b64e2156.49b1e","type":"udp out","name":"","addr":"","iface":"","port":"","outport":"","base64":false,"multicast":"false","x":629,"y":534,"z":"6b5c7d92.94a384","wires":[]},{"id":"65fc2e61.9a03d","type":"debug","name":"","active":true,"console":"false","complete":"true","x":432,"y":586,"z":"6b5c7d92.94a384","wires":[]}]

Jon Ove

unread,
Feb 24, 2015, 8:50:26 AM2/24/15
to node...@googlegroups.com
Hi,

This is what I am trying to do: I am "initiating" the communication from node-red, the message is sent to my embedded device, and the embedded device replies. Node-red shows the reply on the debug tab:

[{"id":"c0a379a8.3f5c88","type":"udp in","name":"","iface":"","port":"4002","datatype":"buffer","multicast":"false","group":"","x":267,"y":207,"z":"24865d3.fdb79a2","wires":[["eb1edc5b.14e12"]]},{"id":"58aa9f58.a7556","type":"udp out","name":"","addr":"172.16.20.167","iface":"","port":"4002","outport":"4002","base64":false,"multicast":"false","x":633,"y":314,"z":"24865d3.fdb79a2","wires":[]},{"id":"eb1edc5b.14e12","type":"debug","name":"","active":true,"console":"false","complete":"true","x":506,"y":208,"z":"24865d3.fdb79a2","wires":[]},{"id":"7279a337.8d865c","type":"inject","name":"","topic":"test","payload":"test","payloadType":"date","repeat":"","crontab":"","once":false,"x":280,"y":314,"z":"24865d3.fdb79a2","wires":[["58aa9f58.a7556"]]}]

My embedded device (far end) will reply back to the source port. This is nothing I can control, since this isn't anything I have made. When I bind to port 4002 on the output node, it looks like this port is occupied by the output node, and the input node are unavailable to listen to this port.
I see two solutions to this issue:
1. The bound port is shared between the two UDP nodes.
2. The port is released by the out node after transmit has finished, and then the port is bound by the input node until the next transmit.

Are there any reason that the out node occupies the port even when transmit has finished?

Best Regards,
Jon Ove

Dave C-J

unread,
Feb 24, 2015, 11:30:46 AM2/24/15
to node...@googlegroups.com
Jon,

ok - on same page now :-)....  can you try....
editing   node-red/nodes/core/io/32-udp.js
line 126 - make it
                  //sock.bind(node.outport);
(ie comment it out :-)

See if that behaves...  that will then not try to bind to the outbound port - If it does I'll add it as an option and do it properly :-)

Dave C-J

unread,
Feb 24, 2015, 11:33:07 AM2/24/15
to node...@googlegroups.com
doh... ignore that... that then makes the source random... :-(

Dave C-J

unread,
Feb 24, 2015, 12:20:12 PM2/24/15
to node...@googlegroups.com
Ok - If I use your exact flow but change the IP address for my subnet and point to another machine running the flow I sent above (changed to port 4002) I get
10721 585.623648 9.20.225.71 4002 9.20.225.182 4002 UDP 55 Source port: pxc-spvr-ft  Destination port: pxc-spvr-ft
10724 585.632108 9.20.225.182 41565 9.20.225.71 4002 UDP 66 Source port: 41565  Destination port: pxc-spvr-ft

and the answer comes back as expected... so errr.. it's working...
( I had to turn off local firewall to let data back in but....)

Jon Ove

unread,
Feb 25, 2015, 3:57:43 AM2/25/15
to node...@googlegroups.com
I also got it working now, but there is something strange: It looks like the sequence the nodes are inserted in decides if it is working or not. 
If I select the inject node and the input node , press ctrl+x to cut the nodes, and then ctrl+v to paste them back in again, and then deploy it, it isn't working. 
However, if I select the output node and the debug node, ctrl+x, ctrl+v and then deploy, it is working! 
Either there is something strange with my installation / setup, or something strange with node-red. 
Do you see the same?

Jon Ove

unread,
Feb 25, 2015, 6:32:07 AM2/25/15
to node...@googlegroups.com
My last post had some errors, here is how it should be:

I also got it working now, but there is something strange: It looks like the sequence the nodes are inserted in decides if it is working or not. 
If I select the inject node and the UDP output node , press ctrl+x to cut the nodes, and then ctrl+v to paste them back in again, and then deploy it, it isn't working. 
However, if I select the UDP input node and the debug node, ctrl+x, ctrl+v and then deploy, it is working! 

Dave C-J

unread,
Feb 25, 2015, 9:11:59 AM2/25/15
to node...@googlegroups.com
ok a really bad hack is to change line 86 of node-red/nodes/core/io/32-udp.js to be
            setTimeout( function() { server.bind(node.port,node.iface); }, 500);
This basically delays the bind of the in port for 0.5 s to let the out port bind first... 
Of course this won't work if you use partial deploys and you only re-deploy the flow with the out port in...
but should work for full deploys... mostly...  as I said.. it's a bad hack while I think about it some more.

Dave C-J

unread,
Feb 25, 2015, 9:13:09 AM2/25/15
to node...@googlegroups.com
oops I mean line 84

ResoTek Inc

unread,
Sep 12, 2016, 1:17:42 PM9/12/16
to Node-RED
I am still experiencing the same UDP problem as Jon, now with node-RED v 0.14.6: I am sending a UDP command from Node-RED to an embedded device. The embedded device sends its UDP responses to the source port seen in the received command UDP packet header, which is common practice, but does not seem to be compatible with Node-RED udp nodes.

I am using the "udp out" node "bind to local port" to specify a static local port number. The static port assignment is necessary so that the listening port in the  "udp in" node can be assigned to listen for the response from the embedded device. However, it seems that Node-RED UDP does not allow binding a listening port to the same port number used by a "udp out" local port binding: a "port in use" message is displayed in Node-RED. According to tcpdump, the remote device sent the UDP response to the Node-RED port configured in the "udp in" node, but the "udp in" node did not output any messages according to the debug node.

If I were to configure the "udp out" node bind to a random local port, then the response would be received on a random local port, and most likely ignored.

If I understand your solution correctly, you delay the bind of the in port. However, it seems that I cannot bind the in port once I have used the same port number for the "udp out" node, so I don't see how that would solve this.

Is this a bug? Where can I track the issue status? What is the latest work-around? Thanks.

On Wednesday, February 25, 2015 at 9:13:09 AM UTC-5, Dave C-J wrote:
oops I mean line 84

Dave C-J

unread,
Sep 12, 2016, 4:50:25 PM9/12/16
to node...@googlegroups.com
Hi

which OS ? Is it possible to share that part of your flow ? - a simple loopback works OK

[{"id":"4a872d70.7ad0a4","type":"udp in","z":"3ee56046.c933c","name":"","iface":"","port":"4002","multicast":"false","group":"","datatype":"buffer","x":160,"y":920,"wires":[["e05f077d.99b728"]]},{"id":"66166897.44de48","type":"udp out","z":"3ee56046.c933c","name":"","addr":"172.17.18.58","iface":"","port":"4002","ipv":"udp4","outport":"4002","base64":false,"multicast":"false","x":390,"y":960,"wires":[]},{"id":"e05f077d.99b728","type":"debug","z":"3ee56046.c933c","name":"","active":true,"console":"false","complete":"true","x":330,"y":920,"wires":[]},{"id":"7f7e35e9.3e0d3c","type":"inject","z":"3ee56046.c933c","name":"","topic":"test","payload":"test","payloadType":"date","repeat":"","crontab":"","once":false,"x":157,"y":960,"wires":[["66166897.44de48"]]}]

ResoTek Inc

unread,
Sep 12, 2016, 7:30:57 PM9/12/16
to Node-RED
Thanks. I am using a BeagleBone Black running Debian to send UDP commands and listen for responses. I pasted your flow onto the Linux beaglebone 4.4.9-ti-r25 (Debian) host, and set the destination IP to raspberrypi, which I'm using to simulate the embedded device. I placed a loopback on the raspberry pi, consisting of a UDP in node listening on port 4002 and a UDP out node. Additionally, I ran tcpdump on both devices.

According to beaglebone # tcpdump the Raspian loopback worked, and a response was sent to the BeagleBone:
18:59:10.430530 IP beaglebone.4002 > raspberrypi.4002: UDP, length 13
18:59:10.462154 IP raspberrypi.35245 > beaglebone.4002: UDP, length 13

However, the beaglebone debug tab did not report any messages received on the beaglebone UDP in node that was listening on port 4002.
The node-RED console output looked normal:
12 Sep 18:58:54 - [info] [udp in:e54eb2a3.737b88] udp listener at 0.0.0.0:4002

Consequently, I placed a loopback on the beaglebone listening on port 4003, and injected a message from the raspberrypi, where I also added a UDP in node listening on port 4003. The symptoms matched the beaglebone: raspberrypi # tcpdump reported that the beaglebone echoed port 4003 data, but the debug node on the Raspberry Pi did not display any echo. The Raspberry Pi is also running Node-RED 0.14.6.

The flows I used on each device are pasted below.

Flows on Beaglebone Black:

[{"id":"e54eb2a3.737b88","type":"udp in","z":"41d11bb.178bb64","name":"","iface":"","port":"4002","multicast":"false","group":"","datatype":"buffer","x":240,"y":660,"wires":[["4565d804.ff7d"]]},{"id":"787d48e0.5cb0f8","type":"udp out","z":"41d11bb.178bb64","name":"","addr":"raspberrypi","iface":"","port":"4002","ipv":"udp4","outport":"4002","base64":false,"multicast":"false","x":460,"y":600,"wires":[]},{"id":"4565d804.ff7d","type":"debug","z":"41d11bb.178bb64","name":"","active":true,"console":"false","complete":"true","x":410,"y":660,"wires":[]},{"id":"5e74722b.64b2bc","type":"inject","z":"41d11bb.178bb64","name":"","topic":"test","payload":"test","payloadType":"date","repeat":"","crontab":"","once":false,"x":230,"y":600,"wires":[["787d48e0.5cb0f8","1f6d509b.7f126f"]]},{"id":"1f6d509b.7f126f","type":"debug","z":"41d11bb.178bb64","name":"","active":true,"console":"false","complete":"false","x":430,"y":560,"wires":[]},{"id":"6da129df.63645","type":"udp out","z":"41d11bb.178bb64","name":"","addr":"","iface":"","port":"","ipv":"udp4","outport":"","base64":false,"multicast":"false","x":870,"y":600,"wires":[]},{"id":"2ebbe3d.e7b901c","type":"udp in","z":"41d11bb.178bb64","name":"","iface":"","port":"4003","ipv":"udp4","multicast":"false","group":"","datatype":"buffer","x":710,"y":600,"wires":[["6da129df.63645","a6b694fd.dc29a"]]},{"id":"a6b694fd.dc29a","type":"debug","z":"41d11bb.178bb64","name":"","active":true,"console":"false","complete":"false","x":890,"y":660,"wires":[]},{"id":"421cd676.da4548","type":"comment","z":"41d11bb.178bb64","name":"Echo on beaglebone is working","info":"","x":770,"y":560,"wires":[]},{"id":"21609331.54d55c","type":"comment","z":"41d11bb.178bb64","name":"beaglebone does not receive Raspian loopback","info":"","x":370,"y":520,"wires":[]}]

Flows on Raspberry Pi:

[{"id":"341c17d6.8683","type":"udp out","z":"18c489a.fe73b76","name":"","addr":"","iface":"","port":"","ipv":"udp4","outport":"","base64":false,"multicast":"false","x":690,"y":700,"wires":[]},{"id":"e7749ea.22c216","type":"udp in","z":"18c489a.fe73b76","name":"","iface":"","port":"4002","ipv":"udp4","multicast":"false","group":"","datatype":"buffer","x":540,"y":700,"wires":[["341c17d6.8683","e2ba3f53.e9ba68"]]},{"id":"e2ba3f53.e9ba68","type":"debug","z":"18c489a.fe73b76","name":"","active":true,"console":"false","complete":"true","x":690,"y":740,"wires":[]},{"id":"e2a78352.aaf678","type":"comment","z":"18c489a.fe73b76","name":"Echo on Raspian is working","info":"","x":600,"y":660,"wires":[]},{"id":"827402aa.01dc4","type":"udp out","z":"18c489a.fe73b76","name":"","addr":"beaglebone","iface":"","port":"4003","ipv":"udp4","outport":"","base64":false,"multicast":"false","x":340,"y":700,"wires":[]},{"id":"2acf8e9f.e61092","type":"inject","z":"18c489a.fe73b76","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":110,"y":700,"wires":[["827402aa.01dc4","9f2a9fe7.de85a"]]},{"id":"9f2a9fe7.de85a","type":"debug","z":"18c489a.fe73b76","name":"","active":true,"console":"false","complete":"false","x":310,"y":740,"wires":[]},{"id":"62f0ebff.998d2c","type":"comment","z":"18c489a.fe73b76","name":"Raspian does not receive Beaglebone loopback","info":"","x":240,"y":660,"wires":[]},{"id":"ba5b4c76.248d68","type":"udp in","z":"18c489a.fe73b76","name":"","iface":"","port":"4003","ipv":"udp4","multicast":"false","group":"","datatype":"buffer","x":120,"y":800,"wires":[["5712b788.79acb"]]},{"id":"5712b788.79acb","type":"debug","z":"18c489a.fe73b76","name":"","active":true,"console":"false","complete":"false","x":300,"y":800,"wires":[]}]

At some point while editing the flows I accidentally had more than one udp node using port 4002 on the Raspian device. This seems to have broken the echo, but after deleting the redundant UDP nodes I got it to work again. I also rebooted Raspian during the troubleshooting, but I don't know whether that was necessary to get it to work again.

TL;DR: both devices can loop back using UDP in and UDP out, but neither reports received UDP in packets if the UDP in port is the same as the port that was bound by the UDP out node.

So why does it work for you, and not for me, neither on Debian nor on Raspian? What OS are you using?

Dave C-J

unread,
Sep 15, 2016, 2:24:24 PM9/15/16
to Node-RED
Hi

finally in a position with the correct bits of kit... and yeah woah... it works fine on my laptop... but as you said, on a Pi the packet doesn't get reported... 
starting to dig

ResoTek Inc

unread,
Sep 16, 2016, 8:53:19 AM9/16/16
to Node-RED
Thanks for the update, the suspense was eating at me. I'm glad you were able to reproduce the problem. What OS are you running on your laptop? Let me know if you need me to install node-RED on a Linux Intel laptop. Good luck with your hunting. Keep in mind that the Beaglebone Black is exhibiting the same behaviour as the Raspberry Pi.

Dave C-J

unread,
Sep 16, 2016, 5:19:02 PM9/16/16
to node...@googlegroups.com
Ok,

I have patched up the udp node and now it detects if the port is already used by another input or output and re-uses it if necessary. This lets it do wrap back.

After some more testing I'll post it to master.

Mike Bell

unread,
Sep 17, 2016, 12:50:35 PM9/17/16
to Node-RED
Dave,

Now that you have sorted the problem with the udp nodes, I'll mention something I put off for fear of confusing the issue. I've had a similar difficulty with the tcp nodes, where if I have an output node connected and try to deploy an input node listening on the same port I get an error like this:

unable to listen on port 1099, error: Error: listen EADDRINUSE


If you think I am I doing something wrong, I'll gladly supply specifics, but I wonder if this could be the result of some code or logic shared between the two types of node.


Regards,

Mike

Dave C-J

unread,
Sep 17, 2016, 1:23:49 PM9/17/16
to node...@googlegroups.com

Let's start another thread, and you can add examples etc.

Mike Bell

unread,
Sep 17, 2016, 2:03:30 PM9/17/16
to Node-RED
OK. My current problem involves third-party hardware and software that would be hard for you to replicate and might be causing the trouble. I'll try to come up with a clean test case.

Dave C-J

unread,
Sep 17, 2016, 6:49:07 PM9/17/16
to node...@googlegroups.com
Mike

just fyi - did you try setting the out node to a "reply to" node - should share more nicely...
(and it doesn't have to be a reply if don't want/wire it to be so :-)

ResoTek Inc

unread,
Sep 19, 2016, 4:20:50 PM9/19/16
to Node-RED
Dave,

Thanks for your work in resolving this issue. Thanks to your fix, we can now receive UDP packets on the same port number that is found in the FROM address of the UDP packets that are sent by the UDP OUT node. Meanwhile, I came across this closed github issue that may be related, and thought it may be relevant to your tying up or documenting loose ends on this issue: UDP Out Node locks out local UDP port unnecessarily #165.

Since the above use case is so common (replying to an incoming packet's FROM IP:PORT), I wonder whether it's appropriate to display a "port is already in use" warning in Node-RED whenever a UDP OUT node port is reused by a UDP IN node, or if that warning should be suppressed. I realize that the coding effort to carve out an already-in-use exception is unexpectedly complex due to the many cases that must be considered, and may not be worth the effort. There are probably more pressing areas to expend your coding time.

Thanks again.

Dave C-J

unread,
Sep 19, 2016, 4:38:07 PM9/19/16
to node...@googlegroups.com
Well - by default it's usually easier for the sending port to use a random port...  - binding to a fixed port is actually extra work. So by implication would seem to be the not-normal use case. So indeed for now I'm going to leave it setting the warning... - it only does it once on deploy and is only a warning so can be ignored. 

Yes the closed issue was where we started having to do the extra work to bind in the first place...

Mike Bell

unread,
Sep 19, 2016, 4:53:15 PM9/19/16
to Node-RED
Dave,

Good catch, but not quite a solution. Actually, I have been using a tcp request node -- how nicely it behaves seems to depend on what happens at the other end. The context is that I am running a local process that communicates via tcp. It and node-RED seem to be fighting for the right to listen on a particular port. I think I have the option of opening another port on the process, so I'll see if that works rather than try to figure out exactly how to eliminate the conflict. If I run into a dead end, I'll start another thread as you suggest.
Regards,
Mike

Dave C-J

unread,
Sep 19, 2016, 5:22:13 PM9/19/16
to node...@googlegroups.com
Mike

if they insist on listening ... then maybe the tcp-request node may be a better bet ?

Mike Bell

unread,
Sep 19, 2016, 6:50:54 PM9/19/16
to Node-RED
Dave,

Agreed. The process I am trying to communicate with responds to requests, BUT it also sends data when triggered by an external event. So node-RED needs to listen even when it has not sent a request. I think separate ports for the two functions may be the right answer, if I can get it working. Thanks for the advice.

Regards,
Mike

Dave C-J

unread,
Sep 20, 2016, 3:31:40 AM9/20/16
to node...@googlegroups.com
Mike, 
thought the tcp-request node also has a "keep the connection open" mode ....
Reply all
Reply to author
Forward
0 new messages