如何使用GCDAsyncUdpSocket在局域网中广播?

时间:2013-12-05 03:32:53

标签: ios iphone networking broadcast

我想在GCDAsyncUdpSocket的未知IP地址的局域网中发现是否有正在侦听特定端口的服务器。我将在局域网中广播一些消息,如果服务器存在,它将反馈消息,然后我将知道服务器的IP地址。

现在我尝试使用以下代码来完成工作:

udpSocket = [[GCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];

if (![udpSocket bindToPort:18686 error:&error])
{
    [self logError:FORMAT(@"Error binding: %@", error)];
    return;
}

if (![udpSocket beginReceiving:&error])
{
    [self logError:FORMAT(@"Error receiving: %@", error)];
    return;
}

NSString *host = @"192.168.2.139"; // server IP i know
int port = 8585;
NSString *message = @"Hello";
NSData *data = [msg dataUsingEncoding:NSUTF8StringEncoding];
[udpSocket sendData:data toHost:host port:port withTimeout:-1 tag:tag];

如果我将主机IP设置为服务器IP,它可以,服务器将响应。但我想广播找到服务器IP,我尝试使用“192.168.2.0”,“192.168.2.1”,“192.168.2.255”,“255.255.255.255”,以上所有地址都不能广播。

我想知道哪个IP地址可以用于在192.168.2。*中在LAN中广播,如果不知道LAN IP域则要广播哪个IP地址?任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:7)

我检查了GCDAsyncUdpSocket.h并找到了名为- (BOOL)enableBroadcast:(BOOL)flag error:(NSError **)errPtr;的函数我将以下内容添加到setupSocket

if (![udpSocket enableBroadcast:YES error:&error]) {
        [self logError:FORMAT(@"Error enableBroadcast:%@",error)];
        return;
}

然后广播工作......

对我的问题,我检查了192.168.2。* LAN广播IP是192.168.2.255,未知的LAN广播IP是255.255.255.255。

我不知道为什么我们需要在GCDAsyncUdpSocket中启用广播来使用广播IP。希望有一天这会有所帮助。

答案 1 :(得分:0)

我发现以下(工作)代码可用于为您的计算机连接的所有网络生成所有潜在的广播地址:

+ (NSDictionary *)allNetworks {
    NSMutableDictionary *networkStates = [NSMutableDictionary new];
    SCDynamicStoreRef storeRef = SCDynamicStoreCreate(NULL, (CFStringRef)@"FindCurrentInterfaceIpMac", NULL, NULL);
    if (storeRef) {
        NSDictionary *interfaceInfo = CFBridgingRelease(SCDynamicStoreCopyValue(storeRef, CFSTR("State:/Network/Interface")));
        NSArray *primaryInterfaces = interfaceInfo[@"Interfaces"];
        for (NSString* interfaceName in primaryInterfaces) {
            NSString *interfaceStateKey = [NSString stringWithFormat:@"State:/Network/Interface/%@/IPv4", interfaceName];
            NSDictionary *ipv4State = CFBridgingRelease(SCDynamicStoreCopyValue(storeRef, (__bridge CFStringRef)interfaceStateKey));
            if (ipv4State != nil) {
                networkStates[interfaceName] = ipv4State;
            }
        }
        CFRelease(storeRef);
    }
    return networkStates;
}

返回的字典将网络接口名称作为键,值将是具有键@"地址",@" BroadcastAddresses"和@&#34的字典; SubnetMasks"和字符串数组作为值。要将此添加到您的代码中,您需要包含

#import <SystemConfiguration/SCDynamicStore.h>

并链接到SystemConfiguration.framework。