Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

udp didReceiveData receiving two times

I have the problem that I send an udp Message (broadcast) to a client and get an answer, but this will be displayed two times. When I check the communication an my PC with an UDP listener there is only one message.

May be, someone can give me an info how I can resolve this.

I am using a button to start sending the message!

#import "ViewController.h"
#import "GCDAsyncUdpSocket.h"

@interface ViewController ()
{
    long tag;
    GCDAsyncUdpSocket *udpSocket;

}

@end

@implementation ViewController

- (void)setupSocket
{   udpSocket = [[GCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];

    NSError *error = nil;

    if (![udpSocket bindToPort:1000 error:&error])
    {
        NSLog(@"Error binding: %@", error);
        return;
    }
    if (![udpSocket beginReceiving:&error])
    {
        NSLog(@"Error receiving: %@", error);
        return;
    }

    [udpSocket enableBroadcast:YES error: &error];

    NSLog(@"Ready");
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    if (udpSocket == nil)
    {
        [self setupSocket];
    }
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (IBAction)send:(id)sender{
    NSString *host = @"192.168.2.255";
    if ([host length] == 0)
    {
        NSLog(@"Address required");
        return;
    }

    NSLog(@"%@",host);

    int port = 8888;

    NSString *msg = @"1,0,1,2";

    NSData *data = [msg dataUsingEncoding:NSUTF8StringEncoding];
    [udpSocket sendData:data toHost:host port:port withTimeout:-1 tag:tag];

    NSLog(@"SENT (%i): %@", (int)tag, msg);

    tag++;

}

- (void)udpSocket:(GCDAsyncUdpSocket *)sock didReceiveData:(NSData *)data
        fromAddress:(NSData *)address
        withFilterContext:(id)filterContext
{
    NSString *msg = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

    if (msg)
    {
        NSLog(@"RECV: %@", msg);
        tag++;
        NSLog(@"%li",tag);
    }
    else
    {
        NSString *host = nil;
        uint16_t port = 0;
        [GCDAsyncUdpSocket getHost:&host port:&port fromAddress:address];

        NSLog(@"RECV: Unknown message from: %@:%hu", host, port);
    }
}

@end

Here ist the output!

2013-09-11 09:49:00.132 udptest[5145:907] 15
2013-09-11 09:49:08.218 udptest[5145:907] 192.168.2.255
2013-09-11 09:49:08.220 udptest[5145:907] SENT (15): 1,0,1,2
2013-09-11 09:49:08.319 udptest[5145:907] RECV: 0,0,0,0,0,0,0,0
2013-09-11 09:49:08.321 udptest[5145:907] 17
2013-09-11 09:49:08.323 udptest[5145:907] RECV: 0,0,0,0,0,0,0,0
2013-09-11 09:49:08.324 udptest[5145:907] 18

I would be very grateful if someone could help me.

like image 692
user2767850 Avatar asked Sep 11 '13 08:09

user2767850


1 Answers

I have the same strange unwanted and unresolved behaviour: "sender" sends one broadcast UDP message and "receiver" gets two messagges.

I've investigated as much as I could and these are my findings:

1) Wireshark gets only one UDP message.

2) udpSocket:didReceiveData:fromAddress:withFilterContext: gets fired two times!

3) Parsing the "address" param with [GCDAsyncUdpSocket getHost:port:fromAddress:] results in host = ::ffff:192.168.1.118 the FIRST time while host = 192.168.1.118 the SECOND time.

Hope it would be helpful in some manner...

EDIT (with a possible SOLUTION)

The FIRST address (see points 2 and 3) is an actual IPv6 address. So I guess that the udpSocket:didReceiveData:... is fired two times beacuse the first time the sender is the IPv6 address and the second time the sender is the IPv4 address of the same address.

And so my solution is to enable only the IPv4 in the UDP socket:

[udpSocket setIPv4Enabled:YES];
[udpSocket setIPv6Enabled:NO];
like image 192
LucaM Avatar answered Oct 17 '22 00:10

LucaM