Problem sending datagram through AsyncUdpSocket

Discussion in 'Mac Programming' started by isthisonetaken, Feb 27, 2011.

  1. isthisonetaken macrumors regular

    Joined:
    Jun 29, 2006
    #1
    Hey guys,

    I'm using AsyncUdpSocket to create a UDP connection between a client and server. I want to send a bunch of pictures from the server to the client. I have the client bound to a specific port, and the server has a socket which is connected to the client on that port. I have code to get the picture and send the data to the client:

    Code:
    NSString *path = @"/path/to/picture";
    NSData *picture = [[NSData alloc] initWithContentsOfFile:path];
    NSLog(@"[picture length] = %ld", [picture length]);
    
    [socket sendData:picture withTimeout:WRITE_TIMEOUT tag:DATAGRAM];
    
    where WRITE_TIMEOUT is defined as 5.0 and DATAGRAM as 1

    When I try to send the datagram, it winds up calling the onUdpSocket:didNotSendDataWithTag:dueToError method. I have it telling me the error in a log message and I get this:
    There was an error sending the datagram: Error Domain=NSPOSIXErrorDomain Code=40 UserInfo=0x20008c4e0 "Message too long"

    All I'm trying to send as can be seen from above is the picture. I have my other code for doing a header commented out for now, I just want to send the picture. The picture is about 15kb large.

    Any ideas what to do to fix this?
     
  2. mfram macrumors 65816

    Joined:
    Jan 23, 2010
    Location:
    San Diego, CA USA
    #2
    I don't know the details of the class. It seems to be an open-source library available on the net. So I'm not sure of the limitations of the implementation.

    But I will point out that UDP wasn't really designed for this kind of use. It's designed for very small messages (about 1500 bytes at the most). In this case you seem to want to send a lot more than that.

    I would try using the class in TCP mode. You will probably get much better results.
     
  3. isthisonetaken thread starter macrumors regular

    Joined:
    Jun 29, 2006
    #3
    Ok, for my server, it was throwing an error because the default size of the UDP port buffer for receiving data is only 9216 bytes, and therefore my picture was too big. I changed the size to be 65535 so it's now big enough.

    My new problem is that the server is creating the datagram and sending it, the delegate method is being called once the datagram is written out. I ask for it in the client, but the delegate method that is supposed to be called once it's done being read into the app is never being called...

    This is a link to the header for AsyncUdpSocket. Can anyone see something that I've missed?
    http://code.google.com/p/cocoaasyncsocket/source/browse/trunk/AsyncUdpSocket.h?r=68
     
  4. Cromulent macrumors 603

    Cromulent

    Joined:
    Oct 2, 2006
    Location:
    The Land of Hope and Glory
    #4
    As mfram has stated you really should be using TCP.

    There is no guarantee when using UDP that the message will even reach the client at all. UDP works best for real time apps such as games where if a packet is lost then it is not such a big deal and it is better to keep getting data in the future rather than keep trying to send / receive the same data until the client acknowledges proper receipt.
     
  5. isthisonetaken thread starter macrumors regular

    Joined:
    Jun 29, 2006
    #5
    This is a simple (I thought) streaming app where the client has a movie (a folder of pictures) that I want to send to the client one after the other to display in the client as a movie. Therefore, if I lose a picture here or there, it isn't a huge deal. I get that UDP is not the most reliable method to send data, but it shouldn't not send data every single time I try to run the app?
     
  6. chown33, Feb 27, 2011
    Last edited: Feb 27, 2011

    chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #6
    UDP doesn't guarantee that datagrams are sent in sequence, that they are received in sequence, that they are received at all, that the size sent is the size received, or a host of other things. If you've never actually used UDP before, some of this may seem incredible.

    I have used AsyncUdpSocket before and it works, as far as it goes. What you are intending to do with it, however, is beyond the capabilities of UDP. Again, if you've never used UDP or AsyncUdpSocket before, this may seem incredible.

    You could try to layer things on top of UDP to work around limitations like out of sequence, or whatever. At some point, though, you will just be reinventing TCP, but much more poorly and bug-riddled. You will be better off just going with TCP in the first place.


    You've neglected to post your code. Reading AsyncUdpSocket's header isn't going to tell us what's in your client code or your delegate. For example, AsyncUdpSocket needs a run-loop in order to perform delegate callbacks. If your client doesn't run an NSRunLoop the right way, nothing happens.
     
  7. jiminaus macrumors 65816

    jiminaus

    Joined:
    Dec 16, 2010
    Location:
    Sydney
    #7
    Have you considered the effect of intermediate routers? It's definitely possible that a router would not accept a UDP packet this big as a self-defence measure.
     

Share This Page