2016-05-20 22 views
1

私は2つのApplaction 1つはクライアント(IOSデバイス)で、もう1つはサーバー(PCデバイス)です。クライアントのIPアドレスを自動的に取得する方法

クライアント(IOSデバイス)のIPアドレスを自動的に取得したいと考えています。

私はIPアドレス

NSString *ipAddressText = @"192.168.211.62"; 

を入力するコード行を使用しているIPアドレスは、ほとんどの時間を変更しますbecuase私は、IPアドレスを入力して維持する必要はありません。

は、ここに私のコード

-(void)viewDidLoad{ 
      [super viewDidLoad]; 


      NSString *ipAddressText = @"192.148.211.42"; 

      NSLog(@"Setting up connection to %@ : %i", ipAddressText, 111); 
      CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, (__bridge CFStringRef) ipAddressText, 111, &readStream, &writeStream); 
      messages = [[NSMutableArray alloc] init]; 
      [self open]; 
     } 

    - (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent { 

     NSLog(@"stream event %lu \n ", streamEvent); 

     switch (streamEvent) { 

      case NSStreamEventOpenCompleted: 
       NSLog(@"Stream opened"); 
       _connectedLabel.text = @"Connected"; 
       break; 
      case NSStreamEventHasBytesAvailable: 

       if (theStream == inputStream) 
       { 
        uint8_t buffer[1024]; 
        NSInteger len; 

        while ([inputStream hasBytesAvailable]) 
        { 
         len = [inputStream read:buffer maxLength:sizeof(buffer)]; 
         if (len > 0) 
         { 
          NSString *output = [[NSString alloc] initWithBytes:buffer length:len encoding:NSASCIIStringEncoding]; 

          if (nil != output) 
          { 
           NSLog(@"server said: %@ \n ", output); 
           [self messageReceived:output]; 
          } 
         } 
        } 
       } 
       break; 

      case NSStreamEventHasSpaceAvailable: 
       NSLog(@"Stream has space available now"); 
       break; 

      case NSStreamEventErrorOccurred: 
       NSLog(@"%@\n",[theStream streamError].localizedDescription); 
       break; 

      case NSStreamEventEndEncountered: 

       [theStream close]; 
       [theStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 
       _connectedLabel.text = @"Disconnected"; 
       NSLog(@"close stream"); 
       break; 
      default: 
       NSLog(@"Unknown event"); 
     } 

    } 

     - (void)open { 

      NSLog(@"Opening streams."); 

      outputStream = (__bridge NSOutputStream *)writeStream; 
      inputStream = (__bridge NSInputStream *)readStream; 

      [outputStream setDelegate:self]; 
      [inputStream setDelegate:self]; 

      [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 
      [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 

      [outputStream open]; 
      [inputStream open]; 

      _connectedLabel.text = @"Connected"; 
     } 


    - (void)close { 
     NSLog(@"Closing streams."); 
     [inputStream close]; 
     [outputStream close]; 
     [inputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 
     [outputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 
     [inputStream setDelegate:nil]; 
     [outputStream setDelegate:nil]; 
     inputStream = nil; 
     outputStream = nil; 

     _connectedLabel.text = @"Disconnected"; 
    } 
+0

これはDNSが – Paulw11

+0

のためのものです。@ Paulw11は、サーバーからIPアドレスを自動的に読み取る方法はありません。 –

+0

同じネットワーク上にいる場合、bonjourのようなブロードキャスト/マルチキャストプロトコルを使用できます – Paulw11

答えて

1

これは、スウィフトにあるのですが、簡単に任意のXcodeプロジェクトにドロップすることができます。

NB:この例は、GitHubプロジェクトHost.swiftから取ったものです。

iOSやMac OS XなどのUnixタイプのシステムでネットワークインタフェースに関する情報を取得するには、いくつかの難解なC APIを使用する必要があります。これらのAPIは、および,およびにさまざまな可視性を持ちます。

Objective-CでmacOSを排他的にターゲティングする場合は、が最適です。ただし、iOSとの互換性が必要な場合は、getifaddrs(...)またはのような低レベルのC APIにドロップダウンする必要があります。

getifaddrs(...)にも、ベースのソリューションが必要な場合は、いくつかのブリッジヘッダー要件があります(フレームワークでは使用できなくなります)。

ここでは、CFHostsockaddr_in structを使用して、SwiftとmacOSとiOS(フレームワークでさえも)で動作する例を示します。完全に動作する例については、GitHibのHost.swiftを参照してください。

  1. 使用CFHostのアドレッシング情報を取得するには、これはCFArrayCFDataのオブジェになります。

    let sockaddrs = CFHostGetAddressing("apple.com", &resolved)?.takeRetainedValue() 
    
  2. let data = CFArrayGetValueAtIndex(sockaddrs, 0) 
    
  3. は、私たちは

    let addr = withUnsafePointer(&storage) { UnsafePointer<sockaddr_in>($0).memory 
    
    それを使用することができますsockaddr_in structsockaddr structを強制その後sockaddr struct

    var storage = sockaddr_storage() 
    data.getBytes(&storage, length: sizeof(sockaddr_storage)) 
    
  4. にバイトをキャスト最初のオブジェクトを取得します。

  5. inet_ntoa(...)関数を使用して、addr.sin_addr(IPアドレス)をC文字列に変換します。 String(Cstring: encoding:)を使用して、IPアドレスの素敵な文字列を取得することができます。

    let address = String(CString: inet_ntoa(addr.sin_addr), encoding: NSUTF8StringEncoding) 
    

は、ここで私は上記の手法を用いてこれらの問題を解決するために作成したHost.swift呼ばGitHubのプロジェクトです。

関連する問題