Iphone udp接收数据两次
我有一个问题,我发送一个udp消息(广播)到客户端,并得到一个答案,但这将显示两次。当我检查我的电脑与UDP侦听器的通信时,只有一条消息 也许,有人可以告诉我如何解决这个问题 我正在使用一个按钮开始发送消息Iphone udp接收数据两次,iphone,udp,xcode4.3,Iphone,Udp,Xcode4.3,我有一个问题,我发送一个udp消息(广播)到客户端,并得到一个答案,但这将显示两次。当我检查我的电脑与UDP侦听器的通信时,只有一条消息 也许,有人可以告诉我如何解决这个问题 我正在使用一个按钮开始发送消息 #import "ViewController.h" #import "GCDAsyncUdpSocket.h" @interface ViewController () { long tag; GCDAsyncUdpSocket *udpSocket; } @end
#import "ViewController.h"
#import "GCDAsyncUdpSocket.h"
@interface ViewController ()
{
long tag;
GCDAsyncUdpSocket *udpSocket;
}
@end
@implementation ViewController
- (void)setupSocket
{ udpSocket = [[GCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
NSError *error = nil;
if (![udpSocket bindToPort:1000 error:&error])
{
NSLog(@"Error binding: %@", error);
return;
}
if (![udpSocket beginReceiving:&error])
{
NSLog(@"Error receiving: %@", error);
return;
}
[udpSocket enableBroadcast:YES error: &error];
NSLog(@"Ready");
}
- (void)viewDidLoad
{
[super viewDidLoad];
if (udpSocket == nil)
{
[self setupSocket];
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)send:(id)sender{
NSString *host = @"192.168.2.255";
if ([host length] == 0)
{
NSLog(@"Address required");
return;
}
NSLog(@"%@",host);
int port = 8888;
NSString *msg = @"1,0,1,2";
NSData *data = [msg dataUsingEncoding:NSUTF8StringEncoding];
[udpSocket sendData:data toHost:host port:port withTimeout:-1 tag:tag];
NSLog(@"SENT (%i): %@", (int)tag, msg);
tag++;
}
- (void)udpSocket:(GCDAsyncUdpSocket *)sock didReceiveData:(NSData *)data
fromAddress:(NSData *)address
withFilterContext:(id)filterContext
{
NSString *msg = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
if (msg)
{
NSLog(@"RECV: %@", msg);
tag++;
NSLog(@"%li",tag);
}
else
{
NSString *host = nil;
uint16_t port = 0;
[GCDAsyncUdpSocket getHost:&host port:&port fromAddress:address];
NSLog(@"RECV: Unknown message from: %@:%hu", host, port);
}
}
@end
这是输出
2013-09-11 09:49:00.132 udptest[5145:907] 15
2013-09-11 09:49:08.218 udptest[5145:907] 192.168.2.255
2013-09-11 09:49:08.220 udptest[5145:907] SENT (15): 1,0,1,2
2013-09-11 09:49:08.319 udptest[5145:907] RECV: 0,0,0,0,0,0,0,0
2013-09-11 09:49:08.321 udptest[5145:907] 17
2013-09-11 09:49:08.323 udptest[5145:907] RECV: 0,0,0,0,0,0,0,0
2013-09-11 09:49:08.324 udptest[5145:907] 18
如果有人能帮助我,我将不胜感激。回复信息和请求信息的内容是否相同。如果是,那么您可能会遇到一个场景。可能是第一个数据包是您正在收听的广播,第二个数据包是响应。更准确地说,当您发送广播(pkt p1)时,发送方也可以获得p1的副本。接下来,当接收器发送响应(pktp2)时,您也会看到响应
那么,我们如何验证它呢。您可以查看发件人地址(UDP提供了一个选项),然后检查它是您的地址还是其他主机的地址。我有同样奇怪的不想要的和未解决的行为:“发件人”发送一条广播UDP消息,“收件人”收到两条消息 我已经尽我所能进行了调查,以下是我的发现: 1) Wireshark只获取一条UDP消息 2) udpSocket:didReceiveData:fromAddress:withFilterContext:被激发两次 3) 使用[GCDAsyncUdpSocket getHost:port:fromAddress:]解析“address”参数第一次会导致host=::ffff:192.168.1.118,而第二次会导致host=192.168.1.118 希望它能在某种程度上有所帮助 编辑(使用可能的解决方案) 第一个地址(见第2点和第3点)是实际的IPv6地址。 所以我猜udpSocket:didReceiveData:。。。触发两次,因为第一次发送方是IPv6地址,第二次发送方是相同地址的IPv4地址 因此,我的解决方案是只在UDP套接字中启用IPv4:
[udpSocket setIPv4Enabled:YES];
[udpSocket setIPv6Enabled:NO];
谢谢你的回复。我明天会尝试一下,并给出反馈。谢谢你的版本,IPv4和IPv6的东西都很好用!为我工作很好。谢谢你解决了这个问题。我有完全相同的问题,这个问题解决了。。。顺便说一下,无需调用
setIPv4Enabled
,默认情况下是这样的——只需禁用IPv6即可。对我来说,这是客户端和服务器是同一台机器的副作用。我猜单次发送的消息会通过物理网络适配器和环回接口发出,因此会被GCDAsyncUdpSocket
接收两次。这是一个非常巧妙的观察结果。请一定投赞成票!对我也有用。但是,在调用.beginReceiving()之前应调用setIPv6Enabled(false),否则仍会激发两次didReceive。