Receiving UDP multicast packets twice

984 views
Skip to first unread message

Ed Anuff

unread,
Apr 12, 2009, 11:47:15 PM4/12/09
to CocoaAsyncSocket
I'm using the following code to receive a UDP packet, however it
appears to be receiving the same packet twice for each send:

listenSocket = [[AsyncUdpSocket alloc] initWithDelegate:self];
if ([listenSocket bindToPort:CHANNEL_PORT error:nil])
{
NSLog(@"bindToPort OK");
}
else
{
NSLog(@"bindToPort Failed");
}
if ([listenSocket joinMulticastGroup:@CHANNEL_GROUP error:nil])
{
NSLog(@"joinMulticastGroup OK");
}
else
{
NSLog(@"joinMulticastGroup Failed");
}
[listenSocket receiveWithTimeout:-1 tag:1];


- (BOOL)onUdpSocket:(AsyncUdpSocket *)sock didReceiveData:(NSData *)
data withTag:(long)tag fromHost:(NSString *)host port:(UInt16)port
{

//do stuff here

[listenSocket receiveWithTimeout:-1 tag:2];

return YES;
}

If I check the tag on the second receive, it's using the tag set when
I call receiveWithTimeout inside onUdpSocket.

Any idea what I'm doing wrong?

Thanks in advance,
Ed

Robbie Hanson

unread,
Apr 13, 2009, 12:25:46 AM4/13/09
to cocoaasy...@googlegroups.com
Is this happening for every single UDP packet, or just some of them?

What/who is sending the UDP packets? Is it possible the UDP packets are
being sent twice?

-Robbie Hanson
-Deusty Designs

Ed Anuff

unread,
Apr 13, 2009, 1:48:03 AM4/13/09
to CocoaAsyncSocket
On Apr 12, 9:25 pm, Robbie Hanson <robbiehan...@deusty.com> wrote:
> Is this happening for every single UDP packet, or just some of them?
>
> What/who is sending the UDP packets? Is it possible the UDP packets are
> being sent twice?

It happens for every single packet. If I view the UDP traffic with
Wireshark, it looks like the packets are only being sent once.

I'm sending and receiving in the same program. I created a modified
version of the EchoServer example that uses UDP to test this. You can
view it here:

http://pastebin.com/f6b050074

Thanks

Ed

Robbie Hanson

unread,
Apr 13, 2009, 1:38:24 PM4/13/09
to cocoaasy...@googlegroups.com
Hi Ed,

I found the problem.  If you print out the host address in the "onUdpSocket:didReceiveData:withTag:fromHost:port:" method, you'll notice that one is IPv4 and the other is IPv6.

When I first noticed this, I assumed that AsyncUdpSocket was accidentally joining multiple multicast groups, or accidentally sending the data over both IPv4 or IPv6.  However, after tracing the code I found out this was not the case.  It appears that somewhere outside of the application the multicast packets are being forwarded over both IPv4 and IPv6...  But could this possibly be correct?  I assumed if this was indeed happening, it had to be a bug in the router.  I was connected to an apple airport extreme.  So I switched over to our D-Link router and tried again.  Same result.  So I disconnected from all networks and tried again.  Same result.  It appears that this is occurring within the OS.  Whether or not this is a bug, or a design of multicast, I'm not entirely sure.

A quick workaround for the existing revision of AsyncUdpSocket will fix the issue:

// sendSocket = [[AsyncUdpSocket alloc] initWithDelegate:self];
sendSocket = [[AsyncUdpSocket alloc] initIPv4];
[sendSocket setDelegate:self];

// listenSocket = [[AsyncUdpSocket alloc] initWithDelegate:self];
listenSocket = [[AsyncUdpSocket alloc] initIPv4];
[listenSocket setDelegate:self];

AsyncSocket and AsyncUdpSocket both transparently support both IPv4 and IPv6.  This makes it very easy to write forward-looking code, especially servers.  However, if you do something strictly in one IP version, AsyncUdpSocket will close the other IP version.  So, for example, if you bind to an IPv4 interface, AsyncUdpSocket will close the IPv6 socket.  Or, if you connect to an IPv6 address, AsyncUdpSocket will close the IPv4 socket.  Etc.  The same thing *should* have been happening when you joined an IPv4 multicast group.  But there was a bug in the code, and this was not happening.  I've fixed this bug, and committed the changes.  So if you grab the latest revision, your code should work perfectly as-is.

(However, if you know you're only going to be using IPv4, you may want to consider using the IPv4 constructors anyways.)

-Robbie Hanson
-Deusty Designs



Ed Anuff

unread,
Apr 13, 2009, 7:48:11 PM4/13/09
to CocoaAsyncSocket
Thanks Robbie, it looks like that was exactly the problem.
Reply all
Reply to author
Forward
0 new messages