GCDAsyncUdpSocket и многоадресная передача и прием
В первом подходе я создаю клиент-серверное приложение на основе sampleProject, которое отправляет некоторые данные на сервер.
Legend:
sender
address = reciver ip
port = reciver port
reciver
address = null since he is listening
port = in my case 55555
Рабочий код
пропуская проверку ошибок преднамеренно только по общественным причинам
Отправитель
-(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++;
}
Приемник/слушатель
-(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
}
Multicast
Но тогда я хочу, чтобы клиент отправил много приемников. Форма Я знаю, что sendre или слушатель должен использовать [GCDAsyncUdpSocket joinMulticastGroup: error];. Я столкнулся с переполнением стека, дядюшкой google и CococaAsyncSocket (где нет слова abou udp), сопоставил собранные фрагменты информации и придумал этот код. Я совершенно уверен, что это не работает, но я не знаю, почему.
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++;
}
Приемник/слушатель
-(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
}
UPDATE:
Получается, что когда я использую некоторый IP-адрес для использования в качестве address
, например, @ "224.0.1.1", то он прокручивается, но немного странно. Правильно ли я делаю это?
Ответы
Ответ 1
-
Многоадресные адреса являются специальными зарезервированными адресами для целей многоадресной рассылки. Когда хост отправляет данные в групповой адрес (группу), все узлы, которые присоединились к этой группе, будут получать данные.
-
Любой хост, который хочет получать данные из группы многоадресной передачи, должен присоединиться к этой группе. Три шага для GCDAsyncUdpSocket: (обратите внимание, что групповой адрес и комбинация группового порта должны быть уникальными для выбранной группы многоадресной рассылки)
[_udpSocket bindToPort:_port error:&error];
[_udpSocket joinMulticastGroup:_address error:&error];
[_udpSocket beginReceiving:&error])
-
Для отправителя вам не нужны эти две строки, как у вас.
[_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.
Используйте 239.0.0.0-239.255.255.255 для своей частной локальной сети. Избегайте 224... Подробнее вы можете прочитать по ссылке выше.