In first approach I create client-server app ,based on sampleProject , which send some data to server.
Legend:
sender
address = reciver ip
port = reciver port
reciver
address = null since he is listening
port = in my case 55555
skipping error checking is intentional only for public reasons
Sender
-(id*)initForSender:(NSString*)address port:(int)port
{
self = [super init];
if (self) {
_port = port;
_address = address;
tag = 0;
_udpSocket = [[GCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
[_udpSocket bindToPort:0 error:&error];
[_udpSocket beginReceiving:&error];
return self;
}
}
-(void)send:(NSData*)data{
[_udpSocket sendData:data toHost:_address port:_port withTimeout:-1 tag:tag];
tag++;
}
Receiver / Listener
-(id*)initForReceiver:(NSString*)address port:(int)port
{
self = [super init];
if (self) {
_port = port;
_udpSocket = [[GCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
NSError *error = nil;
[_udpSocket bindToPort:0 error:&error];
[_udpSocket beginReceiving:&error];
}
return self;
}
- (void)udpSocket:(GCDAsyncUdpSocket *)sock didReceiveData:(NSData *)data
fromAddress:(NSData *)address
withFilterContext:(id)filterContext
{
//Do something with receive data
}
But then I want client which will send to many receivers. Form I know sendre or listener should use [GCDAsyncUdpSocket joinMulticastGroup:error];. I ran throu stackoverflow, uncle google and CococaAsyncSocket (where is no word abou udp), match gathered pieces of information and came up with this code. I'm perfectly sure, that is not working but I don't have a clue why.
Legend:
sender
address = sender ip
port = sender port in my case 55555
reciver
address = sender ip
port = sender port in my case 55555
-(id*)initForSender:(NSString*)address port:(int)port
{
self = [super init];
if (self) {
_port = port;
_address = address;
_udpSocket = [[GCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
NSError *error = nil;
[_udpSocket bindToPort:_port error:&error];
[_udpSocket joinMulticastGroup:_address error:&error];
[_udpSocket enableBroadcast:YES error:&error];
}
return self;
}
-(void)send:(NSData*)data{
[_udpSocket sendData:data toHost:_address port:_port withTimeout:-1 tag:tag];
tag++;
}
Receiver / Listener
-(id*)initForReceiver:(NSString*)address port:(int)port
{
self = [super init];
if (self) {
_port = port;
_address = address;
_udpSocket = [[GCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
NSError *error = nil;
[_udpSocket bindToPort:_port error:&error];
[_udpSocket joinMulticastGroup:_address error:&error];
[_udpSocket beginReceiving:&error])
}
return self;
}
- (void)udpSocket:(GCDAsyncUdpSocket *)sock didReceiveData:(NSData *)data
fromAddress:(NSData *)address
withFilterContext:(id)filterContext
{
//Do something with receive data
}
It's turn out that when I use some unuse IP as address
for example @"224.0.1.1" then it wroks, but it feels weird a bit. Am I doing it correct?
Multicast addresses are special reserved addresses for multicasting purpose. When a host send a data to a multicast address (group), all hosts that have joined that group will receive the data.
Any host that wishes to receive data from a multicast group needs to join that group. The three steps for GCDAsyncUdpSocket are: (note that group address and group port combination must be unique for that selected multicast group)
[_udpSocket bindToPort:_port error:&error];
[_udpSocket joinMulticastGroup:_address error:&error];
[_udpSocket beginReceiving:&error])
For a sender, you don't need these two lines as you have.
[_udpSocket bindToPort:0 error:&error]; //bindToPort:0 is same as auto-select sender port by default.
[_udpSocket beginReceiving:&error]; //if you don't want to received, no need for this.
Use the 239.0.0.0-239.255.255.255 for your private local network. Avoid 224... You can read more from the link above.