GCDAsyncUDPSocket:虽然发送成功,但没有收到任何数据

Posted

技术标签:

【中文标题】GCDAsyncUDPSocket:虽然发送成功,但没有收到任何数据【英文标题】:GCDAsyncUDPSocket: Not receiving any data though it is successfully sent 【发布时间】:2016-06-01 04:45:45 【问题描述】:

我正在尝试创建一个 UDP 套接字并将数据发送到广播端口,以便我可以在同一 WiFi 网络中的其他设备上接收相同的数据。我正在计算接受的答案here中给出的广播端口的IP地址。

之后我写了一些连接代码如下:

self.udpSocket = [[GCDAsyncUdpSocket alloc]initWithDelegate:self delegateQueue:dispatch_get_main_queue() socketQueue:nil];
NSError *error;
[self.udpSocket enableReusePort:YES error:&error];
[self.udpSocket enableBroadcast:YES error:&error];

- (IBAction)sendMessageToBroadcastPort:(id)sender 
 [self.udpSocket sendData:[@"Hi" dataUsingEncoding:NSUTF8StringEncoding] toHost:[self getUDPBroadcastAddress] port:5556 withTimeout:-1 tag:1];

我成功发送数据作为委托方法 didSendData: 被调用。

请指导我这里缺少什么。

谢谢!

更新: 用于从广播端口接收数据的cpde:

- (void)listenForPackets

dispatch_queue_t dQueue = dispatch_queue_create("client udp socket", NULL);
udpSocket = [[GCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:dQueue socketQueue:nil];
NSError *error = nil;

if (![udpSocket bindToPort:5556 error:&error]) 
    NSLog(@"Error binding: %@",error);//not connecting to host
    return;

if (![udpSocket beginReceiving:&error]) 
    NSLog(@"Error receiving: %@",error);
    return;

NSLog(@"Socket Ready");


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

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

    NSLog(@"RCV: %@", msg);

else

    NSString *host = nil;
    uint16_t port = 0;
    [GCDAsyncUdpSocket getHost:&host port:&port fromAddress:address];
    NSLog(@"Unknown message from : %@:%hu", host, port);


计算得到的广播IP是192.168.2.255

更新 2:

我所面临的情况真的很不同而且很奇怪。接收有时有效,有时无效。 当我安装两个应用程序时,没有收到任何数据。只有发送成功。我保持应用程序打开,一段时间后应用程序开始接收数据。在某些情况下,它会在一段时间后停止接收或继续接收而没有任何问题。可能是什么问题?

【问题讨论】:

您无需致电connectToHost,因为 UDP 连接较少。你应该使用sendData:toHost:port:withTimeout 嘿@Paulw11,你的建议让我很开心!这也很重要:当你只接收时,请不要写 socket.connect(toHost:IP, onPort: PORT)。只有 socket.bind(toPort: PORT) 会开始接收。谢谢:) 【参考方案1】:

尝试如下:

创建一个套接字:

-(void)createClientUdpSocket

    dispatch_queue_t dQueue = dispatch_queue_create("client udp socket", NULL);

    sendUdpSocket = [[GCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue: dQueue socketQueue: nil];
    [sendUdpSocket receiveOnce:nil];
    [sendUdpSocket joinMulticastGroup:[self getIPAddress] error:nil]; // Put your IP Address
    NSLog(@"Ready");

Socket 的委托方法。

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

     NSString *ip = [GCDAsyncUdpSocket hostFromAddress:address];
     uint16_t port = [GCDAsyncUdpSocket portFromAddress:address];
     NSString *s = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
     // Continue to wait for a message to receive the next
     NSLog (@ "The server receives the response [%@:% d]%@", ip, port, s);
     [sock receiveOnce:nil];

     dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^
     [self sendBackToHost:ip port:port withMessage:s];
   );


-(void)sendBackToHost:(NSString *)ip port:(uint16_t)port withMessage:(NSString *)s

      [sendUdpSocket sendData:yourData toHost:yourIP port:5556 withTimeout:60 tag:200];
       NSLog(@"sent message to server");

希望这会有所帮助。它为我工作:)

【讨论】:

感谢您的回复。现在因为我没有连接套接字,所以我没有收到错误,但是当我尝试读取广播 IP 的内容时,示例接收器应用程序没有收到任何内容。我已经用接收者的代码更新了我的问题。或者我计算的IP有什么问题吗?请指导。 我已经根据到目前为止我能做的事情更新了我的问题。请看一看。 现在收到作品但有问题。请检查我更新的问题。 我已经实现了这些代码,但是没有接收数据方法调用,我得到了 IP 地址,但是流确实没有调用连接方法或任何其他德尔门方法没有调用,请尽快回复【参考方案2】:

我正在回答这个问题,因为我面临的情况非常不同而且很奇怪。接收有时有效,有时无效。 当我安装两个应用程序时,没有收到任何数据。只有发送成功。我保持应用程序打开,一段时间后应用程序开始接收数据。在某些情况下,它会在一段时间后停止接收。

实际上,我使用的是连接到以太网的 Mac 的共享 Internet 连接。我将我的 WiFi 网络更改为适当的宽带网络,从那时起它就可以正常工作了。

希望这可以帮助有类似情况的人:)

【讨论】:

以上是关于GCDAsyncUDPSocket:虽然发送成功,但没有收到任何数据的主要内容,如果未能解决你的问题,请参考以下文章

如何使用GCDAsyncUdpSocket连续发送udp数据包

GCDAsyncUdpSocket 和多播发送和接收

GCDAsyncUdpSocket 套接字在发送 255 个数据包之间关闭

GCDAsyncUdpSocket 在发送到 IPv6 地址时立即关闭

GCDAsyncUdpSocket,“不能多次绑定套接字”

为 GCDAsyncUdpSocket 设置最大数据包大小