UDP packets not always sent out.
I’ve been struggling to try and figure out why Lemur (and also TouchOSC) don’t always update when I sent out some OSC packets from Max.
I finally installed a packet sniffer on my Mac and discovered that in fact Max sometimes doesn’t send the packets out. A [print] object
connected beside the [udpsend] object indicates that [udpsend] is certainly being called properly.
I’m not sure at all what’s going on here but I’m wondering if there are known problems with the [udpsend] object in Max 5 (and Max 6, I tried both).
Interested to know about this as well.
I’ve had similar issues with a custom iOs application. I know that by definition UDP does not check if messages have been received but just throws data to the host like it just don’t care.
It would be great to hear from the devs if it is just an inherent feature that some times packets are dropped or if it is an actual bug with the object.
In my case, it’s not that packets are dropped (i.e, ignored by receiver) but that they don’t sometime don’t even get sent out (according to Wireshark)
Shot in the dark.. try inserting deferlow in front of udpsend.
Good shot but I already tried that yesterday.
Sometimes udpsend’s internal queue can get over run.
Increase the maxqueuesize, it’s in the help file.
So I have tried some more experiments. I created patchers in both Max 5 and in PD that use a metro to send a cycle of messages (A to Z and then back to A again) over udp, one every 500ms. I also wrote a simple UDP Monitor for my iPad and watched the incoming messages and also ran my packet sniffer on the Mac.
I found two things of interest with both Max 5 and with PD.
1) Every now and then there would be a delay (typically 3-5 seconds) during which time nothing showed up on the iPad and then a clump of packets showed up together. No packets were lost (as I could see because of the A-Z pattern of messages).
2) Sometimes, after such a delay, some packets were in fact missing, typically two or three.
When I checked the packet sniffer on the Mac, the packets that were missing on the iPad did NOT show up in the sniffer.
So for some reason (and at this point I have no idea what’s going on), sometimes packets are not even being sent out.
I have to assume that the [udpsend] on Max and PD are implemented differently (The Max version understands OSC but the PD version requires a [packOSC] object and so I’m left to wonder if there’s something more fundamental going on.
Thanks, Andrew, I had tried that yesterday but it didn’t seem to help. Also, these packets are not very big and I assume that once they get sent out, the queue is emptying automatically.
alternatively, you could try my network externals (see http://cycling74.com/forums/topic.php?id=42930 ). However, since they don’t support OSC, you’d need to add the OSC formatting to your messages by hand, which (depending on the difficulty of your data structure) could be quite a painful process…
I looked quickly at your object but didn’t know how to quickly create an OSC message at your object would accept. The OSC messages are very simple, just single messages, but right now I’m trying to figure out whether the problem is with Max (and PD) or whether there is something broken at a lower level, on two of my systems, which is also hard to believe,
If you can provide me with an example of how to send a simple OSC message though your object, I can at least run the tests again to see if there’s any change in behavior.
unfortunately I don’t have an abstraction/object this time that would create binary-formatted OSC messages. However, for testing purposes, you can generate any OSC-formatted binary message using this small test patch:
----------begin_max5_patcher---------- 640.3ocyW98aaBCDG+YxeEd7bWDfgjvdaZur2lzRkllVplbAmhm7OP1l1zU0 +2mwljP1HUzEfsWrkOeAt6iu78LOMyy+VwNrxG7Nv2.ddOMyyyZp1fWyZOeF ZWFEort4mIXLLW6ekaOMdm1Z+8bgt.KARDOWv.ZrRCJExCNxqXhJMEqsOlfF qjb6OVb6Oda3h8ttUv0bDC6dtRBh1dGE4m1cBilu+oThzYED9ceWhyztjIII wrMXocLLFVOEELO.byw3gv2GNg01dd1r5gqtPPrVvvW.ERFRJDtnMEfSHE9p nBjg3NBPLyEDEHSPqXbvCEXaohYvXheOVpHBiYjBnpxxvJ01JZ+IFbHIFL1w J6HbQ7zQrqaSHBk1fFM.weDvLPAcGFnEfOs9CfsBIC8JJphFzhpVDJJcDpo3 3GLQ8e.nRIgqAWaJn5ehGLF0FP6TR5jk4U4kln.StGCRhgQgcm+gMVclzOVh cgsu+g.rEZRGCxDzLsXxPiBkiXyM.ZMlmazTnhLDsPXDc9aHko.qSXsZDfUi nb5HvpF0hgnLY4Hj4wMhqN.r5bYdzkm4GJS13+QLkJ.eQHo4uYi+PfljgWT0 QlUwCOXdQM0M9Gapnw4mCOcHvBGgFKN40vn+AhHe1oxJMucSsZ2TH5bEITRc moyKhLFMgaDbShmxdQJiTaKg1WfUc0Rd3ov9K4+Jff0CyIF+2+3G6Ko19ojQ IpjY6Ona9yO336I2boDBGoMWiskOgm3SAIOGyaSEFIuTXpVZBAvMcdJ02HZY OhnUSZDE0iHBNoQTZeN0B9uCR0Gsg8OhhhmmTqiFXayFAcppsWAs2ccYPPsi 0KNIILKdd1u.6erx5. -----------end_max5_patcher-----------
OK, I was able to modify my test to use your object and I’m seeing the same behavior, actually in some ways even worse. I saw several delays, some missing items in the sequences and at one point I started getting error messages in the Max window
sadam.udpSender: Can’t send data to ’192.168.0.187′ on UDP port 8000
I’m not sure yet why it thought it couldn’t send data out….in fact I’m wondering if that’s somehow a clue as to what might be wrong.
definitely a clue. Didn’t you also get an error message on the rightmost outlet at the same time when you got the ‘Can’t send data…’ stuff? (If not, you might need to enable the ‘verbose’ attribute of the object.) Could you please tell the error code as well?
I didn’t see any right most outlet — not sure what you mean.
This is what I used
----------begin_max5_patcher---------- 768.3oc0W10SaCCEF95zeEVQiqVoKGm37wtZncEZ2M1cSnozDSqmRriRbDvP 7ee1NIPYP9XEHPUE0MGeh664gWebyMKrrWKthVYi9L5mHKqaVXYYBoCX0dsk cd7UIYwUlzrSD44TtzdYybR5URS7yX4EYTThnlKokniQWRQEkhz5DJRtkhN4 rud5onKDklqpKJnkIwUTD1GkQkpaopaIyXbpYYzqqaavhXYxVFeyuJoIxF8h AmUNKUKPfd.H95AuvUNnyauIVpQZh0+9XLzs7WH3RdbN0L0Ikr3rtY304LtR LlBE1I8J1eLoCX0Wwc4JpkcI6nCd6hE52V9LA4O1RUXY80RZEpjVTpthKMPS mBhwMetpnjwkWfT0lFHOE5v8iNOrqAVXnAcd5AWumFcPzgB59thU2E8IJaHv Tn.zLPZ7ON8T1j2akMmdoRXOppqhSiyWUmVbFkmp15AQ3UfuZevJHL.EB.dH j3ZbBD89FEKfvgPxqpQnK4lPxqKnMJzlosymuG7JmVUEug9Hf4onhGBb.kXb TtAeT.QaJT+oBANsiDjKF46ghh1YB+l6q8ypD9.fbTu77LCNiiZOeylNBFaL g8zu5+scE9EA06Gm6yW11h5S+PE4akBtnB8kDk9z8yNJKc.TgiL9P2PmFFMn qDBeSrkunr5iHex3VG21AuAwQvah0Yu2k1CQNRcv93DAGzZTFjHdGXDoNeMs bBEOX9kOibLl6q4tC7PE+Rj85X9lW3MJv.fgP1gKt3Uj94R3gkmnuyxfAsIM Gw.j6wQem2Db.cdy9vhFmADfGGEjC+idyoxRgpwfy3Dowb3SFpGh6aBQ1+dG RwlMYzQqcRTWQ2eoiGrG49tq27MYdZs+4YuMZUG+gUWkntLoa0Z+4gn60aJs Rx3wRlfuSNQOHmsrzTpY5t+MjyRKDJo0JgdH8jUTvDjDLqRBOAE49tSQAyph bmfhHyphHSPQgyphljyddMRf6DoDLaRJ7.kR5mNXN0j2TzTv6vd2OmMcpKtc weQGGfhm -----------end_max5_patcher-----------
OK, typo. I meant ‘leftmost’. Although the object has only a single outlet, so at the end of the day, it’s the same… ;-)
----------begin_max5_patcher---------- 791.3oc2X10SaCCEF951eEGEMtZPWNNNesqFZWg1cic2DZJMwzloF6HGGALD +2msSxnLZgjRIkMgTcywN1umm75iS41oSblKtlU4.eD9NLYxsSmLwFxDXR60 SbJRtNcURkcXNb1Uh4+z43ltTrqU1vkxbtBXRIWz02kBtpJ+WLS+HYlaa3xD U5xb9heHYoplUFIt5tA+HeSSf8SSH3h16gWWjyWwTVIfsAyyrqrVMmPWeM4I E10z4TYdxJm6mBQspaNbMAua5TyGG2yLOUTTv3pGk5mmWTthAohZthIgSfqX PoTjUmx.0RFb54e9ryfKER6U0kkLYZRECHAfVN5aopaJWkyY1owLudCGiwgV xERMMnefogFM.NRvCIH+1RlFKyuQwp.IqTpuR6oLPyLDHma+dk0pcIn0qIy2 D5HCFcTz5.ojnFzYInGc.nCiOjn6qZVo1gMdAnMeIMM9tCdmG5OFo8VJ5Tkj kTLqNq7bFOSu0CiIyv.8ivYXTHDgHo6VZVe0MkrlD2I23TtXmqT42TiBiFLv FrMA2AdUvppRVvdDvnZpPAzEMIBfX.D5qazgPcHzss0G7HP.EhiWqifl6q86 5A7NDb0+Qo1F2sh5W.moAV.6SHV+4VKkQ1fwbL3717kskn9v2zQ9hTvEUvmR 05vTO6nUY6UTQZN0zKJrgQC2RhQGPV8d848uR6R8ntckweJhrIyS3AjHGoey fWIh7GuxvIBcTHRcwbl7IS9iAm4I7EuDHPrFhc4vNugBAx9biBtucETxZ7vi LyeflhnC4YY398.GLt4MgH2yhAcdS3+OrnwVfgw6HJ7OfEOKXJoPu2d6uNxt V8nkJMFjm62ntAp3MFTQIVrXEqe0I1ZNFDzkbCr9H44SD6bY+0Z+0+0AqZLw eX1UIpkocxu885f6UTFqRkyST4B9ZiI9AiYYdVFy1c2S2h7rRglEsR.tXijt 2JJrGRBGUIQ5gh7dyonvQUQd8PQ9iph76ghhFUE0Km83ZjPudRIbzjTz+nTx 7N8ioln8QSguAqcOta5h6gjdIO4zWb2ze6OsCZC -----------end_max5_patcher-----------
I’m wondering the ‘errno’ values when you get the errors. It would be also interesting to see if you get 0 as errno at the time when your packages get dropped/delayed.
Have you tried sending your data to another computer running max?
Another shot in the dark but might be a way to see if it is actually the [udpsend ] object being unreliable or something on the receiving end.
I know that the sniffer should prove this wrong but have generally had good results communicating between laptops.
Just me 2p
Well, I just wrote and tested a simple command line application that sends a sequence of OSC messages out to my iPad where I’m monitoring the results.
Wireshark continues to indicate that some packets don’t even get sent out and that fits with what I’m seeing (and not seeing) on the iPad.
So this would seem to have nothing to do with Max (which I suppose makes sense, it was hard to believe that udpsend was really broken) and there’s something much more fundamental going on. I’ve unstalled my firewall (little snitch) and that made no difference either.
Very bizarre but I no longer consider this to be a Max issue.
Another comment. If you get the error number, you might want to check up that error number on the internet (they are standard *NIX errno values, which you can access for example here: http://www.barricane.com/c-error-codes-include-errno ). My guess is that for each message that gets lost (in other words: each message that wouldn’t show up in Wireshark) you’ll get back a "can’t send data…" message with an errno. I really hope that decoding the errno value will actually tell you the reason why some of your messages wouldn’t be sent out.
Hope this helps,
Adam, after removing little snitch I tried your version again, this time connecting the output to a [print].
I got 0 for a long time and then I started seeing the error
sadam.udpSender: Can’t send data to ’192.168.0.187′ on UDP port 8112
and an output value of -1
However, I didn’t immediately stop the test and after about 15 seconds, the error message stopped being generated and it started transmitting again properly.
I’m not sure if your source code is available — what kinds of things cause you to send out that "Can’t send data" error message?
This is just very strange.
OK, this was an ugly bug that I just fixed. For some weird reason it was sending -1 instead of the actual errno value, but that’s no longer the case. Please download the library again for the fixed version.
The sadam Library is a weird project in the sense that, although it’s free and the license is allowing the end-users to use the objects for commercial purposes (except for one single object which is using a GPLv2 code, therefore that object is also GPL-ed and it’s source code is revealed), it is closed-source. Therefore, the source code of these objects is not available. This has to do mainly with my personal convictions…
With that said, the "can’t send data…" messages are generated when the following code line returns with a negative value:
result = sendto ( socketDescriptor, ( const char * ) iterator, size, 0, ( const struct sockaddr * ) & address, sizeof ( address ) );
result is a
socketDescriptor is either an
int (Mac OS) or a
SOCKET (Win32) representing the socket used for data transmission,
iterator is an
unsigned char * that points to a pre-allocated array of characters in the memory containing the data to send,
size is an
unsigned long that represents the size of the previously mentioned array and
address is a
struct sockaddr_in that holds the address of the remote address where the messages should be sent.
socketDescriptor is created with a call to
socketDescriptor = socket ( PF_INET, SOCK_DGRAM, IPPROTO_UDP );
and is bound to a port before executing any sendto messages with a call to
bind ( socketDescriptor, ( const struct sockaddr * ) & address, sizeof ( address ) );
Additionally, on Windows, I start up the Winsock stuff with a call to
WSAStartup ( MAKEWORD(1, 1), & wsaData ) ); before anything else.
This is not exactly the source code (error checking etc. is omitted here as well as some tricks to make things smaller but less readable), but this should give you a complete picture of what’s happening under the hood.
Hope this helps,
Are you creating a local network through built-in wifi? Recently I moved to using a airport express after all sorts of stability issues, including loosing connection. I have just started working with touch-osc and used it so far in two performances, without any issues. In my case however data is sent in one direction only. Conclusion for me anyway is to avoid using built-in wifi (2008 unibody).
OK —- I have now done enough experiments that I’m pretty sure that the issue is related to wireless connections.
I tried Miguel’s suggestion and set up a Max patcher on my laptop to receive the test messages from my desktop machine. Both machines are on the same subnet, connected by Ethernet. All packets were received perfectly fine with no obvious delays.
I then disconnected my laptop from Ethernet and reconnected through wifi. Desktop still connected to LAN via ethernet.
This time, reception of packets was slightly irregular and very occasionally a packet did not arrive. They didn’t get lost as often as on the iPad but it happened!
So it really looks like UDP is not reliable over wireless, even in a small environment where all the devices (including the router) are physically close. This is disappointing.
I’ve used Lemur successfully to send commands to Max for some time but typically these were fader movements and even if one packet was getting lost occasionally, it wouldn’t really have mattered. The problem is only noticable when I go the other direction and I’m sending TEXT labels and sending them just once. I might try adding in a hack where I store each outgoing text value in a [pv] and send it out twice over a period of a second but what a pain.
Siska, I updated your library and the only non-zero error number I saw occasionally was -64. But I didn’t see that error when packets were being missed occasionally so that seems more like a more generally connectivity problem.
Thanks to everyone for suggestions and feedback. This has been quite illuminating if not disappointing.
this sounds really weird. Standard error numbers (reported by ‘errno’, whose value in my code is saved into an
int just after calling
sendto) are supposed to be positive numbers. So I really can’t imagine what’s happening there. However, if for some reason this is actually the positive value 64, then it corresponds with the ‘Host is down’ error, according to Apple’s version of errno.h. Since UDP doesn’t really keep track of the packages, this doesn’t make too much sense, though. I don’t know how much this helps you after all…
PS: Feel free to call me on my first name (which is Ádám).
PS2: It might also happen that there’s something wrong with your wireless router. I participated on several concerts where we had to do the rehearsals in small rooms with only the in-house wireless network available. Although we usually send a load of UDP and TCP messages, most of the time we don’t experience the problems that you described above.
@Ádám —- sorry — from your username, I assumed your first name was "Siska"
I don’t believe it’s the router because (a) I’ve done these experiments with two separate routers and (b) I also tested with Adhoc connection between laptop and iPad. It seems to be a general problem with UDP over wifi.
I don’t know how you’re using UDP for your rehearsals….having a couple of packets get lost when you’re doing continuous change (e.g, fader movement) won’t matter but when you’re sending a single UDP packet to change the text of a label and that packet gets lost, it’s a different problem.
I just built a "SendTwice" object that stores an incoming value in a private [pv] and then forwards it immediately and then again after a delay. Inserting those into my object that sends various text messages to Lemur has "solved" the problem sufficiently that I can move on.
What a pain, though.
I’ve seen problems like this with encrypted wireless networks.
The way I currently have my stage wireless network set up is to hide the network, only allow connections by MAC address, and turn encryption and all security off.
Andrew, my stage wireless network is setup exactly that way as well, no encryption, no passwords, using MAC address to allow only my iPads and iPhone to connect. My laptop has an ethernet connection so only the devices are wireless.
One of my business partners who has just been experimenting with sending audio over UDP has told me he has seen exactly the same problem with UDP packets getting dropped occasionally. It does seem to be just "what you get" with UDP.
If my SendTwice hack doesn’t suffice, I’ll considering building a little TCP-UDP "echoer" for my iPad. This would allow me to send TCP packets from Max to the iPad and then echoer would resend them to localhost over UDP, thereby getting them to Lemur. I’m trying to prepare for several upcoming tours (which is what got me started with Lemur to replace one of my physical control surfaces in the first place) so I really don’t want the distraction. Thank goodness Max makes it so easy to throw in hacks to work around issues!
now that you mentioned it, you’re right. Probably we didn’t notice the drops with continuous data. And you’re right, we never use UDP to send messages where it is important to avoid dropped packages. For that purpose, we’ve always used TCP (either my own TCP objects or the
Hope that helps,
@dhjdhjdhj is it only the ipad you need to connect?
I recently finished a project were I was sending data to 50 ipod touches. It was basically a glorified metronome to keep 50 brass players in sync (reading from a dead tree score) as they were distributed all over the place at a mall thus making it impossible for the piece to be conducted. I had the same issues you describe, packages being lost now and then. I tried something similar to what you describe (re-sending each message more than once) but this resulted in a lot of jitter. Each performer was getting all the messages but not in sync. I haven’t done any strain tests after the concert to see how many devices can be used reliably but just pointing out that flooding the network might create other issues. Probably not a problem for you if you are only connecting the one ipad.
@Adam got your updated library today and love the new feature that gets the IP of the remote client! great work.
I will look at TCP objects but assume that at this stage that would only work with other computers? it would be interesting if LEMUR and TouchOSC added the option to use TCP as well.
Yes, I just want to send information reliably to Lemur. I wish Liine could be persuaded to support TCP as well as UDP.
I looked into building a little background app on the iPad that would receive TCP packets from an external connection and forward the data to ‘localhost’ in UDP packets. I figured that Lemur could be persuaded to listen to ‘localhost’
However, the problem is that iOS doesn’t want to allow network apps to continue running in the background so unless I can figure a way around that, I’m stuck.