开发通过 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];
}