20

我正在制作一个应用程序来发送UDP数据包以打开LED bulb. 当我连接到Ad-hocWifi bridge.

现在,我想配置它Wifi bridge以便它可以连接到我的主路由器。我设置了 AT 命令来执行此过程,但不知何故我无法接收到Wifi bridge我发送给它的命令的响应。

程序如下:-

  • 第 1 步:发送 UDP 消息到 LAN 广播 IP 地址“10.10.100.255”和端口 48899 =>“Link_Wi-Fi”
    LAN 上的所有 Wifi 网桥都会响应它们的详细信息。响应为“10.10.100.254,ACCF232483E8”

  • 第 2 步:(更改 wifi 网桥上的设置可选):然后发送“+ok”到 LimitlessLED Wifi 网桥。向步骤 1 返回的响应 IP 地址发送 UDP 消息 "10.10.100.254" => "+ok"

  • 第 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 命令来配置网桥。

谢谢。任何帮助将不胜感激。

4

2 回答 2

2

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

1-我假设您正在使用ARC,因此请确保您的udpSocket变量在整个异步通信中具有强引用。如果它被释放,那么这可以解释没有回调。

2- 确保交流真的按照你想象的方式进行。使用诸如Wireshark捕获网络上正在交换的数据包之类的软件。这应该可以让您确认您的数据包确实在呼叫时发送sendData:,它还可以让您确认您是否收到回复。

3-确保您使用GCDAsyncUdpSocket正确。考虑到您要广播消息,您不应该调用bindToPort:error:您的setupSocket方法。相反,您应该调用enableBroadcast:error:. 考虑到您还想在广播后接收数据包,您应该使用该connectToHost:onPort:error:方法更改套接字的状态以允许双向通信。完成后,您可以替换您对sendData:toHost:port:withTimeout:tag:by的使用sendData:withTimeout:tag:。最后,您可以调用beginReceiving:,以便为任何传入的数据包调用委托。

4- 如果这仍然不能让您通过它,我建议您通读 GCDAsyncUdpSocket 的文档,该文档非常有据可查。

于 2015-04-24T05:43:36.207 回答
1

您可以使用 Wireshark 或任何网络捕获工具解决问题。我们曾经在广泛使用 Wireshark 的类似项目中工作。如果数据包已到达设备(Z-Wave),它将发送某种 Ack。这将有助于确保数据包被发送出去。

于 2015-05-06T21:34:17.600 回答