GCDAsyncUDPSocket: данные не получены, хотя они успешно отправлены

Я пытаюсь создать сокет UDP и отправить данные на широковещательный порт, чтобы я мог получать их на других устройствах в той же сети WiFi. Я рассчитываю IP-адрес широковещательного порта, как указано в принятом ответе здесь.

После этого я написал некоторый код подключения, который выглядит следующим образом:

self.udpSocket = [[GCDAsyncUdpSocket alloc]initWithDelegate:self delegateQueue:dispatch_get_main_queue() socketQueue:nil];
NSError *error;
[self.udpSocket enableReusePort:YES error:&error];
[self.udpSocket enableBroadcast:YES error:&error];

- (IBAction)sendMessageToBroadcastPort:(id)sender {
 [self.udpSocket sendData:[@"Hi" dataUsingEncoding:NSUTF8StringEncoding] toHost:[self getUDPBroadcastAddress] port:5556 withTimeout:-1 tag:1];
}

Мне удается отправить данные, когда вызывается метод делегата didSendData:.

Пожалуйста, помогите мне понять, что мне здесь не хватает.

Спасибо!

ОБНОВЛЕНИЕ: Cpde для получения данных от широковещательного порта:

- (void)listenForPackets
{
dispatch_queue_t dQueue = dispatch_queue_create("client udp socket", NULL);
udpSocket = [[GCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:dQueue socketQueue:nil];
NSError *error = nil;

if (![udpSocket bindToPort:5556 error:&error]) {
    NSLog(@"Error binding: %@",error);//not connecting to host
    return;
}
if (![udpSocket beginReceiving:&error]) {
    NSLog(@"Error receiving: %@",error);
    return;
}
NSLog(@"Socket Ready");
}

 - (void)udpSocket:(GCDAsyncUdpSocket *)sock didReceiveData:(NSData *)data
  fromAddress:(NSData *)address
withFilterContext:(id)filterContext
{
NSString *msg = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
if (msg)
{
    NSLog(@"RCV: %@", msg);
}
else
{
    NSString *host = nil;
    uint16_t port = 0;
    [GCDAsyncUdpSocket getHost:&host port:&port fromAddress:address];
    NSLog(@"Unknown message from : %@:%hu", host, port);
}
}

IP-адрес вещания, который я получаю после расчета, равен 192.168.2.255.

ОБНОВЛЕНИЕ 2::

Сценарий, с которым я сталкиваюсь, действительно отличается и странен. Прием иногда работает, а иногда нет. Когда я установил два приложения, данные не были получены. Только отправка прошла успешно. Я оставил приложения включенными, и через некоторое время приложение начало получать данные. В некоторых случаях он переставал получать через некоторое время или продолжал получать без каких-либо проблем. В чем может быть проблема?


person Yogi    schedule 01.06.2016    source источник
comment
Вам не нужно вызывать connectToHost, так как UDP меньше соединения. Вы должны использовать sendData:toHost:port:withTimeout   -  person Paulw11    schedule 01.06.2016
comment
Привет, @Paulw11, твое предложение сделало мой день лучше! Также это очень ВАЖНО: когда вы только получаете, пожалуйста, не пишите socket.connect(toHost:IP, onPort: PORT). Только socket.bind(toPort: PORT) может начать прием. Спасибо :)   -  person iHarshil    schedule 25.02.2020


Ответы (2)


Попробуйте, как показано ниже:

Создайте сокет:

-(void)createClientUdpSocket
{
    dispatch_queue_t dQueue = dispatch_queue_create("client udp socket", NULL);

    sendUdpSocket = [[GCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue: dQueue socketQueue: nil];
    [sendUdpSocket receiveOnce:nil];
    [sendUdpSocket joinMulticastGroup:[self getIPAddress] error:nil]; // Put your IP Address
    NSLog(@"Ready");
}

Метод делегата для Socket.

-(void)udpSocket:(GCDAsyncUdpSocket *)sock didReceiveData:(NSData *)data fromAddress:(NSData *)address withFilterContext:(id)filterContext
{
     NSString *ip = [GCDAsyncUdpSocket hostFromAddress:address];
     uint16_t port = [GCDAsyncUdpSocket portFromAddress:address];
     NSString *s = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
     // Continue to wait for a message to receive the next
     NSLog (@ "The server receives the response [%@:% d]%@", ip, port, s);
     [sock receiveOnce:nil];

     dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
     [self sendBackToHost:ip port:port withMessage:s];
   });
}

-(void)sendBackToHost:(NSString *)ip port:(uint16_t)port withMessage:(NSString *)s{

      [sendUdpSocket sendData:yourData toHost:yourIP port:5556 withTimeout:60 tag:200];
       NSLog(@"sent message to server");
}

Надеюсь, это поможет. У меня работает :)

person Soumya Ranjan    schedule 01.06.2016
comment
Спасибо за ваш ответ. Теперь, когда я не подключаю сокет, я не получаю сообщение об ошибке, но пример приложения-приемника ничего не получает, когда я пытаюсь прочитать содержимое широковещательного IP-адреса. Я обновил свой вопрос с кодом получателя. Или есть какие-то проблемы с моим рассчитанным IP? Пожалуйста, направляйте. - person Yogi; 01.06.2016
comment
Я обновил свой вопрос, основываясь на том, что мне удалось сделать до сих пор. Пожалуйста, посмотрите. - person Yogi; 02.06.2016
comment
Теперь получение работает, но с проблемой. Пожалуйста, проверьте мой обновленный вопрос. - person Yogi; 03.06.2016
comment
Я реализовал этот код, но сделал вызов метода данных Receive, и я получил IP-адрес, но поток не вызывал метод подключения, или любой другой метод delgate не вызывается, пожалуйста, ответьте как можно скорее - person DURGESH; 20.02.2017

Я отвечаю на этот вопрос, поскольку сценарий, с которым я столкнулся, действительно отличается и странен. Прием иногда работает, а иногда нет. Когда я установил два приложения, данные не были получены. Только отправка прошла успешно. Я оставил приложения включенными, и через некоторое время приложение начало получать данные. В некоторых случаях он перестал получать через некоторое время.

На самом деле я использовал общее интернет-соединение моего Mac, которое подключено к Ethernet. Я изменил свою сеть Wi-Fi на подходящую широкополосную сеть, и с тех пор она работает без проблем.

Надеюсь, это поможет кому-то с похожим сценарием :)

person Yogi    schedule 08.06.2016