0

开发通过 WiFi 与 UDP 到串行转换器通信的 iPAD 应用程序。应用程序以广播模式启动并检索响应单元 (requestPodIds) 的列表。接收到的数据将 SN 映射到单元 IP 地址。然后使用选定的 IP 地址在 iPad 和 UDP/串行转换器之间进行点对点通信。

我的代码在广播通信上运行良好。并且转换器正在接收我发送到单元 IP 地址的单播消息(requestStatus),并且它正在按预期响应。但是,我没有将任何数据返回到 didReceiveData 方法中。

我不明白为什么我没有在方法中取回数据:

- (void)udpSocket:(GCDAsyncUdpSocket *)sock didReceiveData:(NSData *)data
      fromAddress:(NSData *)address
withFilterContext:(id)filterContext

我的套接字连接位于 AppDelegate 中,并且调用是来自 viewController 的模式。

viewController 上的按钮按下如下:
1.按钮1单击
2.按钮2点击;这会调用 requestPodIds;工作正常; 返回的数据用 pod id 填充其他十个按钮标签;一个被点击;

3.getPodIdsClick;这将加载 UDP/串行转换器的 IP 地址;

4. 获取状态点击;这就是问题发生的地方。UDP报文出去,UDP转换器接收到报文并响应,在didReceiveData中我从来没有看到响应数据。

AppDelegate 代码:

 - (int) udpServiceStart {
    NSError * UDPError;
    if(GCDUdpSocket == nil)
    {
        GCDUdpSocket = [[GCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
    }
    GCDUdpSocket.delegate = self;
    [GCDUdpSocket setIPv4Enabled:YES];
    [GCDUdpSocket setIPv6Enabled:NO];
    [GCDUdpSocket enableBroadcast:YES error:&UDPError];

    if (![GCDUdpSocket  bindToPort:udpPort error:&UDPError])  { NSLog(@"Error starting server (bind): %@", UDPError);
        return -1;
    }

    if (![GCDUdpSocket beginReceiving:&UDPError])
        //            if (![GCDUdpSocket receiveOnce:&UDPError])
    {
        [GCDUdpSocket close];
        NSLog(@"Error starting server (recv): %@", UDPError);
        return -1;
    }

    NSLog(@"UDP Link started on port %hu", [GCDUdpSocket localPort]);
    return 0;
}

- (void) connectToPodAtAddress: (NSString *) ipAddress
{
    NSError * UDPError;
    [GCDUdpSocket enableBroadcast:NO error:&UDPError];
    podIp = ipAddress;
//    if (![GCDUdpSocket connectToHost:podIp onPort:udpPort error:&UDPError])
//    {
//        [GCDUdpSocket close];
//        NSLog(@"Error connecting to host: %@", UDPError);
//        return;
//    }
//    if (![GCDUdpSocket beginReceiving:&UDPError])
//        //            if (![GCDUdpSocket receiveOnce:&UDPError])
//    {
//        [GCDUdpSocket close];
//        NSLog(@"Error starting server (recv): %@", UDPError);
//        return;
//    }
}

- (void)udpSocket:(GCDAsyncUdpSocket *)sock didReceiveData:(NSData *)data
      fromAddress:(NSData *)address
withFilterContext:(id)filterContext
{
    //    NSError * UDPError;

    NSString *msg = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

    if (msg)
    {
        NSLog(@"RCV: %@", msg);
        if(!commandBuffer) commandBuffer = [[NSMutableString alloc] initWithString:@""];

        // Append the current message portion to the total message
        [commandBuffer appendString:msg];

        NSString * commands = [[NSString alloc] initWithString: commandBuffer];

        NSInteger cr_index = [commands rangeOfString:@"\r"].location;

        if([commands rangeOfString:@"\r"].location == NSNotFound)
        {
            if([commands rangeOfString:@"~~~ds"].location != NSNotFound)
            {
                [commandBuffer setString:@""];
            }

        } else {
            [self decodeMessage:commands];
        }

    }
    else
    {
        NSString *host = nil;
        uint16_t thePort = 0;
        [GCDAsyncUdpSocket getHost:&host port:&thePort fromAddress:address];
        NSLog(@"Unknown message from : %@:%hu", host, thePort);
    }
    //
    // Queue up to Read Next Message
    //
    //    if (![GCDUdpSocket receiveOnce:&UDPError])
    //    {
    //        [GCDUdpSocket close];
    //        NSLog(@"Error starting server (recv): %@", UDPError);
    //        return;
    //    }


}

- (void)udpSendToHost:(NSString *)host onPort:(int) thePort theMessage: (NSString *) msg
{
    NSData *data = [msg dataUsingEncoding:NSUTF8StringEncoding];
    tag = 0;
    [GCDUdpSocket sendData:data toHost:host port:thePort withTimeout:-1 tag:tag];

    NSLog(@"SENT message for tag (%i) to host %@:%i", (int)tag, host, thePort);
    NSLog(@"Message sent = (%@)", msg);

}

- (void) requestPodIds
{
#ifdef LOGFUNCTIONCALLS
    NSLog(logString,__FUNCTION__);
#endif
    [podTable removeAllObjects];  //    pod_table.Clear(); // Empty table of any previous responses

    if (GCDUdpSocket != nil) // null happens on startup if wireless adapter not found
    {
        //        PodMessage to_pod = new PodMessage(PodCommands.ucget, PodParameters.serial_number);
        PodMessage *to_pod = [[PodMessage alloc] initWithCommand:ucget andParams:serial_number];
        //        int bytes = udp_socket.SendTo(Encoding.ASCII.GetBytes(to_pod.Message()),
        //                                      new IPEndPoint(IPAddress.Broadcast, port));
        [self udpSendToHost:podIp onPort:udpPort theMessage:to_pod.message];
        //        Debug.Assert(bytes == to_pod.Message().Length);
    }
}

- (void) requestStatus
{
    if (GCDUdpSocket != nil) // null happens on startup if wireless adapter not found
    {
        //        PodMessage to_pod = new PodMessage(PodCommands.ucget, PodParameters.serial_number);
        PodMessage *to_pod1 = [[PodMessage alloc] initWithCommand:ucget andParams:status_pod];
        [self udpSendToHost:podIp onPort:udpPort theMessage:to_pod1.message];
//        PodMessage *to_pod2 = [[PodMessage alloc] initWithCommand:ucget andParams:status_line0];
//        [self udpSendToHost:podIp onPort:udpPort theMessage:to_pod2.message];
//        PodMessage *to_pod3 = [[PodMessage alloc] initWithCommand:ucget andParams:status_line1];
//        [self udpSendToHost:podIp onPort:udpPort theMessage:to_pod3.message];
        //        Debug.Assert(bytes == to_pod.Message().Length);
    }
}

来自 ViewController 的访问如下:

wifiTestAppDelegate *appDelegate;

appDelegate = (wifiTestAppDelegate *)[[UIApplication sharedApplication] delegate];

- (IBAction)button1Click:(id)sender {

    [appDelegate udpServiceStart];
}

- (IBAction)button2Click:(id)sender {
    if([GCDUdpSocket isClosed])
    {
        NSLog(@"Socket is Closed!");
    } else {
        if([GCDUdpSocket isConnected])
        {
            NSLog(@"Socket is Connected!  Can't Broadcast!");
        } else {
            [appDelegate requestPodIds];
        }
    }
}
- (IBAction)podSelectClick:(id)sender {

    NSLog(@"Button with label %@",((UIButton *)sender).titleLabel.text);
    NSLog(@"Button with tag %i",((UIButton *)sender).tag);


//    UIButton *button = (UIButton *)[self.view viewWithTag:buttonTag++];
//    [button setTitle:[podTable objectForKey:key] forState:UIControlStateNormal];

    NSString * ipAddress = [podTable objectForKey:((UIButton *)sender).titleLabel.text];
    NSLog(@"IP Address = %@",ipAddress);
    podIp = ipAddress;
    pod_sn = ((UIButton *)sender).titleLabel.text;

    [appDelegate connectToPodAtAddress:ipAddress];

    getStatusButton.hidden = NO;

    [selectPodButton setTitle:ipAddress forState:UIControlStateNormal];
}
- (IBAction)getPodIdsClick:(id)sender {
    int buttonTag = 101;
    NSMutableArray * sortArray = [[NSMutableArray alloc] initWithCapacity:100];
    if([podTable count] > 0)
    {
        for (NSString *key in podTable)
        {
            [sortArray addObject:key];
        }
        [sortArray sortUsingSelector:@selector(compare:)];
        for(int i=0; i < [podTable count]; i++)
        {
            UIButton *button = (UIButton *)[self.view viewWithTag:buttonTag++];
            [button setTitle:[sortArray objectAtIndex:i] forState:UIControlStateNormal];
        }
    }

}

- (IBAction)getStatusClick:(id)sender {
    [appDelegate requestStatus];
}
4

1 回答 1

0

除了类广播之外,让 GCDAsyncUdpSocket 发送没有运气。解决了广播部分代码的 BSD 套接字解决方案的实现:

int                 fd;
int                 err;
int                 junk;
struct sockaddr_in  addr;
NSData *            data;
ssize_t             bytesSent;
static const int    kOne = 1;

fd = socket(AF_INET, SOCK_DGRAM, 0);
assert(fd >= 0);

err = setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &kOne, sizeof(kOne));
assert(err == 0);

data = [@"hello" dataUsingEncoding:NSUTF8StringEncoding];
assert(data != nil);

memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_len = sizeof(addr);
addr.sin_port = htons(8023);
addr.sin_addr.s_addr = htonl(0xffffffff);  // 255.255.255.255

bytesSent = sendto(fd, [data bytes], [data length], 0, (const struct sockaddr *) &addr, sizeof(addr));
NSLog(@"bytes sent = %zd", bytesSent);

junk = close(fd);
assert(junk == 0);
于 2013-06-24T03:26:49.600 回答