美文网首页iOS 进阶
无法使用GCDAsyncSocket接收发送的UDP数据包的响应

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

作者: 路漫漫其修远兮Wzt | 来源:发表于2019-04-30 18:04 被阅读0次

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

    场景:

    客户端向服务端的端口A发送数据,服务端监听端口A;服务端接收到数据包(数据包里面包含客户端端口信息B)后,会向客户端端口B返回一个响应数据;

    需求:

    1.Android中使用socket.receive(data)可以直接接收到服务端的响应数据包;(参考Socket通信入门之基于UDP
    2.iOS使用GCDAsyncSocket怎么接收服务端的响应数据呢?答案是绑定端口0[udpSocket bindToPort:0 error:&error],然后在代理方法-(void)udpSocket:(GCDAsyncUdpSocket *)sock didReceiveData:(NSData *)data fromAddress:(NSData *)address withFilterContext:(id)filterContext中接收服务端响应数据;(参考无法使用GCDAsyncSocket接收发送的UDP数据包的响应?)

    以下是参考文献正文:

    正在制作一个应用程序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命令,以便配置网桥。

    相关文章

      网友评论

        本文标题:无法使用GCDAsyncSocket接收发送的UDP数据包的响应

        本文链接:https://www.haomeiwen.com/subject/erzvnqtx.html