无法使用GCDAsyncSocket接收发送的UDP数据包的响应?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (357)

正在制作一个应用程序UDP数据包,以便打开LED bulb,当连接到Ad-hoc,通过Wifi bridge...

程序如下:

  • 步骤1:向局域网广播IP地址10.10.100.255和端口48899=>“Link”发送UDP消息"Link_Wi-Fi" “ 局域网上的所有Wifi桥都将对其细节作出反应。答复为“10.10.100.254,ACCF 232483E8”
  • 步骤2:(可选用于更改wifi桥上的设置):然后发送“+ok”到有限LED Wifi桥。将UDP消息发送到步骤1“10.10.100.254”=>“+ok”返回的响应IP地址
  • 步骤3:(可选用于更改wifi桥上的设置):在此之后,您可以向模块发送AT命令(以\r\n结尾)。

发送UDP数据包的代码如下

-(void)configureWifi{

    counter++;
    NSString *host = @"10.10.100.255";
    if ([host length] == 0)
    {
        [self logError:@"Address required"];
        return;
    }

    int port = 48899; //[portField.text intValue];
    if (port <= 0 || port > 65535)
    {
        [self logError:@"Valid port required"];
        return;
    }
    NSString *msg = @"Link_Wi-Fi";
    NSData *data = [msg dataUsingEncoding:NSUTF8StringEncoding];
    NSLog(@"the message sent is %@", data);
    [udpSocket sendData:data toHost:host port:port withTimeout:-1 tag:tag];

}

现在,为了设置套接字并接收数据,使用以下两个委托方法:

 - (void)setupSocket
{
    // Setup our socket.
    // The socket will invoke our delegate methods using the usual delegate paradigm.
    // However, it will invoke the delegate methods on a specified GCD delegate dispatch queue.
    // 
    // Now we can configure the delegate dispatch queues however we want.
    // We could simply use the main dispatc queue, so the delegate methods are invoked on the main thread.
    // Or we could use a dedicated dispatch queue, which could be helpful if we were doing a lot of processing.
    // 
    // The best approach for your application will depend upon convenience, requirements and performance.
    // 
    // For this simple example, we're just going to use the main thread.

    udpSocket = [[GCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];

    NSError *error = nil;

    if (![udpSocket bindToPort:0 error:&error])
    {
        [self logError:FORMAT(@"Error binding: %@", error)];
        return;
    }
    if (![udpSocket beginReceiving:&error])
    {
        [self logError:FORMAT(@"Error receiving: %@", error)];
        return;
    }

    [self logInfo:@"Ready"];
}

为了接收数据,这是在发送UDP数据包后调用便条的方法。这是GCDAsyncUdpSocket类,用于发送和接收UDP数据包。

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

        [self logInfo:FORMAT(@"RECV: Unknown message from: %@:%hu", host, port)];
    }
}

一旦我能够收到响应,我将能够发送下一个AT命令,以便配置网桥。

提问于
用户回答回答于

使用Wireshark或任何网络捕获工具,您都可能会遇到麻烦。我们过去在类似的项目中工作,我们广泛使用Wireshark。如果数据包已经到达设备(Z-Wave),它将发送某种Ack。这将有助于确保数据包正在释放。

用户回答回答于

以下是我建议使用的故障排除步骤:

我假设你正在使用,ARC确保你的udpSocket变量在整个异步通信中有一个很强的参考。如果它被释放,那么可以解释没有回调。

2-确保沟通真的以你想象的方式发生。使用一个软件Wireshark来捕获在网络上交换的数据包。

3-确保您GCDAsyncUdpSocket正确使用。考虑到你想广播一条消息,不应该bindToPort:error:在你的setupSocket方法调用。相反,应该enableBroadcast:error:。考虑到希望在广播后接收数据包,应该使用该connectToHost:onPort:error:方法来更改套接字的状态以允许双向通信

4-如果这仍然不能解决问题,建议仔细阅读GCDAsyncUdpSocket的文档,这些文档是非常有用的。

扫码关注云+社区

领取腾讯云代金券