2015-04-24 4 views
2

Мне нужно получить локальный IP-адрес и маску подсети с помощью кода Swift.Как получить адрес IP-адреса локальной и подсети в swift

Пожалуйста, помогите мне в этом. У меня есть код, который работает в Objective-C. Как получить эквивалентный код в Swift?

Ниже я добавил код Objective-C:

+(NSDictionary *)getLocalIPAddress{ 
NSDictionary *dictIPDetails; 
NSString *address = @"error"; 
NSString *netmask = @"error"; 
struct ifaddrs *interfaces = NULL; 
struct ifaddrs *temp_addr = NULL;int success = 0; 

    // retrieve the current interfaces - returns 0 on success 
    success = getifaddrs(&interfaces); 

    if (success == 0) 
    { 
     temp_addr = interfaces; 

     while(temp_addr != NULL) 
     { 
      // check if interface is en0 which is the wifi connection on the iPhone 
      if(temp_addr->ifa_addr->sa_family == AF_INET) 
      { 
       if([@(temp_addr->ifa_name) isEqualToString:@"en0"]) 
       { 
        address = @(inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)); 
        netmask = @(inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_netmask)->sin_addr)); 
        dictIPDetails = @{LOCAL_IP_ADDR:address,SUBNET_MASK:netmask}; 
       } 
      } 

      temp_addr = temp_addr->ifa_next; 
     } 
    } 

    freeifaddrs(interfaces); 

    return dictIPDetails; 
} 

ответ

8

Я модифицированный ответ от here включить маску подсети вместе с ф.

С кодом ниже вы можете сделать что-то вроде этого:

let ip = getIFAddresses().last!.ip 
    let netmask = getIFAddresses().last!.netmask 

Надеется, что это помогает.

struct NetInfo { 
    let ip: String 
    let netmask: String 
    } 

    // Get the local ip addresses used by this node 
    func getIFAddresses() -> [NetInfo] { 
    var addresses = [NetInfo]() 

    // Get list of all interfaces on the local machine: 
    var ifaddr : UnsafeMutablePointer<ifaddrs> = nil 
    if getifaddrs(&ifaddr) == 0 { 

     // For each interface ... 
     for (var ptr = ifaddr; ptr != nil; ptr = ptr.memory.ifa_next) { 
     let flags = Int32(ptr.memory.ifa_flags) 
     var addr = ptr.memory.ifa_addr.memory 

     // Check for running IPv4, IPv6 interfaces. Skip the loopback interface. 
     if (flags & (IFF_UP|IFF_RUNNING|IFF_LOOPBACK)) == (IFF_UP|IFF_RUNNING) { 
      if addr.sa_family == UInt8(AF_INET) || addr.sa_family == UInt8(AF_INET6) { 

      // Convert interface address to a human readable string: 
      var hostname = [CChar](count: Int(NI_MAXHOST), repeatedValue: 0) 
      if (getnameinfo(&addr, socklen_t(addr.sa_len), &hostname, socklen_t(hostname.count), 
       nil, socklen_t(0), NI_NUMERICHOST) == 0) { 
       if let address = String.fromCString(hostname) { 

        var net = ptr.memory.ifa_netmask.memory 
        var netmaskName = [CChar](count: Int(NI_MAXHOST), repeatedValue: 0) 
        getnameinfo(&net, socklen_t(net.sa_len), &netmaskName, socklen_t(netmaskName.count), 
        nil, socklen_t(0), NI_NUMERICHOST) == 0 
        if let netmask = String.fromCString(netmaskName) { 
        addresses.append(NetInfo(ip: address, netmask: netmask)) 
        } 
       } 
      } 
      } 
     } 
     } 
     freeifaddrs(ifaddr) 
    } 
    return addresses 
    } 

Если вам нужно больше наворотов у меня есть эта версия NetInfo, которая просчитывает свои сети и широковещательные адреса, а также.

struct NetInfo { 
    // IP Address 
    let ip: String 

    // Netmask Address 
    let netmask: String 

    // CIDR: Classless Inter-Domain Routing 
    var cidr: Int { 
    var cidr = 0 
    for number in binaryRepresentation(netmask) { 
     let numberOfOnes = number.componentsSeparatedByString("1").count - 1 
     cidr += numberOfOnes 
    } 
    return cidr 
    } 

    // Network Address 
    var network: String { 
    return bitwise(&, net1: ip, net2: netmask) 
    } 

    // Broadcast Address 
    var broadcast: String { 
    let inverted_netmask = bitwise(~, net1: netmask) 
    let broadcast = bitwise(|, net1: network, net2: inverted_netmask) 
    return broadcast 
    } 

    private func binaryRepresentation(s: String) -> [String] { 
    var result: [String] = [] 
    for numbers in (split(s) {$0 == "."}) { 
     if let intNumber = numbers.toInt() { 
     if let binary = String(intNumber, radix: 2).toInt() { 
      result.append(NSString(format: "%08d", binary) as String) 
     } 
     } 
    } 
    return result 
    } 

    private func bitwise(op: (UInt8,UInt8) -> UInt8, net1: String, net2: String) -> String { 
    let net1numbers = toInts(net1) 
    let net2numbers = toInts(net2) 
    var result = "" 
    for i in 0..<net1numbers.count { 
     result += "\(op(net1numbers[i],net2numbers[i]))" 
     if i < (net1numbers.count-1) { 
     result += "." 
     } 
    } 
    return result 
    } 

    private func bitwise(op: UInt8 -> UInt8, net1: String) -> String { 
    let net1numbers = toInts(net1) 
    var result = "" 
    for i in 0..<net1numbers.count { 
     result += "\(op(net1numbers[i]))" 
     if i < (net1numbers.count-1) { 
     result += "." 
     } 
    } 
    return result 
    } 

    private func toInts(networkString: String) -> [UInt8] { 
    return (split(networkString){$0 == "."}).map{UInt8($0.toInt()!)} 
    } 
} 
+0

Код сбоев для адресов ipv6 в функции toInts из-за принудительной разворачивания в функции карты – firecast

2

Вот Mellson простиралась NetInfo переписан для Swift 2 (Хоуп это спасти кого-то еще время, чтобы работать его)

struct NetInfo { 
    // IP Address 
    let ip: String 

    // Netmask Address 
    let netmask: String 

    // CIDR: Classless Inter-Domain Routing 
    var cidr: Int { 
     var cidr = 0 
     for number in binaryRepresentation(netmask) { 
      let numberOfOnes = number.componentsSeparatedByString("1").count - 1 
      cidr += numberOfOnes 
     } 
     return cidr 
    } 

    // Network Address 
    var network: String { 
     return bitwise(&, net1: ip, net2: netmask) 
    } 

    // Broadcast Address 
    var broadcast: String { 
     let inverted_netmask = bitwise(~, net1: netmask) 
     let broadcast = bitwise(|, net1: network, net2: inverted_netmask) 
     return broadcast 
    } 


    private func binaryRepresentation(s: String) -> [String] { 
     var result: [String] = [] 
     for numbers in (s.characters.split {$0 == "."}) { 
      if let intNumber = Int(String(numbers)) { 
       if let binary = Int(String(intNumber, radix: 2)) { 
        result.append(NSString(format: "%08d", binary) as String) 
       } 
      } 
     } 
     return result 
    } 

    private func bitwise(op: (UInt8,UInt8) -> UInt8, net1: String, net2: String) -> String { 
     let net1numbers = toInts(net1) 
     let net2numbers = toInts(net2) 
     var result = "" 
     for i in 0..<net1numbers.count { 
      result += "\(op(net1numbers[i],net2numbers[i]))" 
      if i < (net1numbers.count-1) { 
       result += "." 
      } 
     } 
     return result 
    } 

    private func bitwise(op: UInt8 -> UInt8, net1: String) -> String { 
     let net1numbers = toInts(net1) 
     var result = "" 
     for i in 0..<net1numbers.count { 
      result += "\(op(net1numbers[i]))" 
      if i < (net1numbers.count-1) { 
       result += "." 
      } 
     } 
     return result 
    } 

    private func toInts(networkString: String) -> [UInt8] { 
     return (networkString.characters.split {$0 == "."}).map{UInt8(String($0))!} 
    } 
} 
3

изменил код, чтобы он работает с быстрым 3:


 
    struct NetInfo { 
 
     let ip: String 
 
     let netmask: String 
 
    } 
 
    
 
    // Get the local ip addresses used by this node 
 
    class func getIFAddresses() -> [NetInfo] { 
 
     var addresses = [NetInfo]() 
 
     
 
     // Get list of all interfaces on the local machine: 
 
     var ifaddr : UnsafeMutablePointer<ifaddrs>? = nil 
 
     if getifaddrs(&ifaddr) == 0 { 
 
      
 
       var ptr = ifaddr; 
 
       while ptr != nil { 
 
       
 
       let flags = Int32((ptr?.pointee.ifa_flags)!) 
 
       var addr = ptr?.pointee.ifa_addr.pointee 
 
       
 
       // Check for running IPv4, IPv6 interfaces. Skip the loopback interface. 
 
       if (flags & (IFF_UP|IFF_RUNNING|IFF_LOOPBACK)) == (IFF_UP|IFF_RUNNING) { 
 
        if addr?.sa_family == UInt8(AF_INET) || addr?.sa_family == UInt8(AF_INET6) { 
 
         
 
         // Convert interface address to a human readable string: 
 
         var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST)) 
 
         if (getnameinfo(&addr!, socklen_t((addr?.sa_len)!), &hostname, socklen_t(hostname.count), 
 
             nil, socklen_t(0), NI_NUMERICHOST) == 0) { 
 
          if let address = String.init(validatingUTF8:hostname) { 
 
           
 
           var net = ptr?.pointee.ifa_netmask.pointee 
 
           var netmaskName = [CChar](repeating: 0, count: Int(NI_MAXHOST)) 
 
           getnameinfo(&net!, socklen_t((net?.sa_len)!), &netmaskName, socklen_t(netmaskName.count), 
 
              nil, socklen_t(0), NI_NUMERICHOST)// == 0 
 
           if let netmask = String.init(validatingUTF8:netmaskName) { 
 
            addresses.append(NetInfo(ip: address, netmask: netmask)) 
 
           } 
 
          } 
 
         } 
 
        } 
 
       } 
 
       ptr = ptr?.pointee.ifa_next 
 
       } 
 
      freeifaddrs(ifaddr) 
 
     } 
 
     return addresses 
 
    }

+0

Спасибо за обновление кода для Swift 3. Не могли бы вы предоставить мне пример приложения, поскольку я новичок с сетью? Концепция программирования и Swift 3 ? Я хочу получить локальный IP, подсеть, а также хотел бы рассчитать сетевые и широковещательные адреса. –

0
let theOutput = Pipe() 

func shell(Path:String ,args: String...) -> Int32 { 
    let task = Process() 
    task.launchPath = Path 
    task.arguments = args 
    task.standardOutput = theOutput 
    task.standardError = theOutput 

    task.launch() 
    task.waitUntilExit() 

    return task.terminationStatus 
} 
shell(Path:"/usr/sbin/arp",args: "-a") 

let theTaskData = theOutput.fileHandleForReading.readDataToEndOfFile() 
let stringResult = String(data: theTaskData, encoding: .utf8) 

print(stringResult!) 
+0

Надеюсь, это поможет вам, это может напечатать все ip и Mac вашей подсети, и я использую xcode 8.1 и swift 3 –

Смежные вопросы