【问题标题】:how to broadcast in LAN with GCDAsyncUdpSocket?如何使用 GCDAsyncUdpSocket 在 LAN 中广播?
【发布时间】:2013-12-21 20:31:31
【问题描述】:

我想发现局域网中是否有一台服务器正在侦听特定端口,其 IP 地址未知,GCDAsyncUdpSocket。我会在局域网广播一些消息,如果服务器存在,它会反馈一个消息,然后我就会知道服务器的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 地址广播?任何帮助将不胜感激。

【问题讨论】:

标签: ios iphone networking broadcast


【解决方案1】:

我检查了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。希望有一天这会对其他人有所帮助。

【讨论】:

  • 头文件解释了为什么必须这样做:因为意外的广播可能会给网络造成压力。
【解决方案2】:

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

+ (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;
}

返回的字典将以网络接口名称作为键,值将以@"Addresses"、@"BroadcastAddresses" 和@"SubnetMasks" 键和字符串数组作为值的字典。要将其添加到您的代码中,您需要包含

#import <SystemConfiguration/SCDynamicStore.h>

并链接到 SystemConfiguration.framework。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-14
    • 1970-01-01
    • 2017-07-07
    • 1970-01-01
    • 2016-04-28
    • 2017-07-24
    相关资源
    最近更新 更多