简体   繁体   English

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

[英]Not able to receive response of the sent UDP packets using GCDAsyncSocket

I am making an app to send UDP packets in order to switch on a LED bulb . 我正在制作一个应用程序来发送UDP数据包,以打开LED bulb I have been able to perform all the actions when I am connecting to the Ad-hoc created by the Wifi bridge . 当我连接到Wifi bridge创建的Ad-hoc时,我能够执行所有操作。

Now, I want to configure the Wifi bridge so that it can connect to my main router. 现在,我想配置Wifi bridge以便它可以连接到我的主路由器。 I have the AT command set to perform this procedure but somehow I am not able to receive the response form the Wifi bridge for the commands which I am sending to it. 我有AT命令设置来执行此过程,但不知何故,我无法从Wifi bridge收到我发送给它的命令的响应。

The procedure is as follows:- 程序如下: -

  • Step 1 : Send UDP message to the LAN broadcast IP address of "10.10.100.255" and port of 48899 => "Link_Wi-Fi" 步骤1:发送UDP消息到LAN广播IP地址“10.10.100.255”和端口48899 =>“Link_Wi-Fi”
    All Wifi bridges on the LAN will respond with their details. 局域网上的所有Wifi网桥都会回复他们的详细信息。 Response is "10.10.100.254, ACCF232483E8" 回复是“10.10.100.254,ACCF232483E8”

  • Step 2 : (optional for changing settings on the wifi bridge): Then send "+ok" to the LimitlessLED Wifi Bridge. 步骤2 :(可选择更改wifi网桥上的设置):然后将“+ ok”发送到LimitlessLED Wifi Bridge。 Send UDP message to the response IP address returned from step 1 "10.10.100.254" => "+ok" 将UDP消息发送到从步骤1“10.10.100.254”=>“+ ok”返回的响应IP地址

  • Step 3 : (optional for changing settings on the wifi bridge): After that you may send AT commands (ending with \\r\\n) to the module. 步骤3 :(可选择更改wifi网桥上的设置):之后,您可以向模块发送AT命令(以\\ r \\ n结尾)。

The code for sending the UDP packets is as follows 发送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];

}

Now in order to setup the socket and to receive the data I am using these two delegate methods: 现在,为了设置套接字并接收数据,我正在使用这两个委托方法:

 - (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"];
}

and to Receive data this is the method which is note getting called after sending the UDP packets. 并且为了接收数据,这是在发送UDP分组之后被调用的方法。 This is the delegate method of the GCDAsyncUdpSocket class which I have used in my project in order to send and receive the UDP packets. 这是我在项目中用于发送和接收UDP数据包的GCDAsyncUdpSocket类的委托方法。

- (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)];
    }
}

Once I am able to receive the response I will be able to send the next AT commands in order to configure the Bridge. 一旦我能够收到响应,我将能够发送下一个AT命令以配置桥接器。

Thanks. 谢谢。 Any help will be appreciated. 任何帮助将不胜感激。

Here are the troubleshooting steps I recommend that you use : 以下是我建议您使用的故障排除步骤:

1- I'm assuming you are using ARC so make sure that your udpSocket variable has a strong reference throughout the asynchronous communication. 1-我假设您正在使用ARC因此请确保您的udpSocket变量在整个异步通信中具有强大的参考。 If it is being freed, then that could explain the absence of a callback. 如果它被释放,那么这可以解释没有回调。

2- Make sure the communication is really happening the way you think it is. 2-确保通信以您认为的方式进行。 Use a software such as Wireshark to capture the packets being exchanged on the network. 使用Wireshark等软件捕获网络上正在交换的数据包。 This should allow you to confirm that your packets do get sent upon calling sendData: and it will also allow you to confirm whether or not you are getting a reply back. 这应该允许您确认在调用sendData:时确实发送了数据包,并且它还允许您确认是否收到回复。

3- Make sure you are using the GCDAsyncUdpSocket properly. 3-确保正确使用GCDAsyncUdpSocket Considering you want to broadcast a message, you shouldn't be calling bindToPort:error: in your setupSocket method. 考虑到您要广播消息,您不应该在setupSocket方法中调用bindToPort:error: . Instead you should be calling enableBroadcast:error: . 相反,你应该调用enableBroadcast:error: . Considering you also want to receive packets after broadcasting, you should use the connectToHost:onPort:error: method to change the state of the socket to allow for bidirectional communication. 考虑到您还想在广播后接收数据包,您应该使用connectToHost:onPort:error:方法来更改套接字的状态以允许双向通信。 After that is done, you can replace your usage of sendData:toHost:port:withTimeout:tag: by sendData:withTimeout:tag: . 完成后,您可以替换sendData:toHost:port:withTimeout:tag:的使用sendData:toHost:port:withTimeout:tag: by sendData:withTimeout:tag: . Finally, you can call beginReceiving: so that the delegate gets called for any incoming packets. 最后,您可以调用beginReceiving:以便为任何传入的数据包调用委托。

4- If this still doesn't get you through it, I recommend that you read throughly the documentation of the GCDAsyncUdpSocket which is very well documented. 4-如果仍然没有通过它,我建议您仔细阅读GCDAsyncUdpSocket的文档,该文档已有详细记录。

You can trouble shoot the problem using Wireshark or any network capture tool. 您可以使用Wireshark或任何网络捕获工具来解决问题。 We use to work in similar kind of project where we used Wireshark extensively. 我们用于广泛使用Wireshark的类似项目。 If packet has reached device(Z-Wave ) it will send out some sort of Ack. 如果数据包已到达设备(Z-Wave),它将发出某种Ack。 this will help to make sure packets are getting out. 这将有助于确保数据包正在退出。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM