2017-05-21 8 views
0

getaddrinfo()を使用してパッシブサーバーソケットを作成しています。このアプローチを使用し、ヒントで指定する:このような結果を通じてAI_PASSIVE、AF_UNSPEC、sock_typeのIループは:Cソケットプログラミング:getaddrinfo()とバインドしてデバイスIPサーバーを取得する

for(ai_ptr = addrinfo_res; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next) 

して、ソケットを作成し、最初のaddrinfo_resで見つかったアドレスにバインドします。

bind(ps_fd, ai_ptr->ai_addr, ai_ptr->ai_addrlen) 

私のサーバーがローカルエリアネットワークで使用できるアドレス(0.0.0.0ではなく)をどのように知ることができますか?

私はそれらのすべてのインターフェイスとIPアドレスを見つけるために以下のコード試してみました:

// linked list of structures describing 
    // the network interfaces of the local system 
    struct ifaddrs *ifaddr, *ifa; 
    int n, gai_err; 

    if(getifaddrs(&ifaddr) == FAILURE) { 
     fprintf(stderr, "getifaddrs: %s\n", strerror(errno)); 
     return FAILURE; 
    } 

    // walk through linked list 
    for(ifa = ifaddr, n=0; ifa != NULL; ifa = ifa->ifa_next, n++) { 

     if(ifa->ifa_addr == NULL) 
      continue; 

     int family = ifa->ifa_addr->sa_family; 

     // display interface name, family 
     printf("%-8s %s (%d)\n", ifa->ifa_name, 
       (family == AF_INET) ? "AF_INET" : 
       (family == AF_INET6) ? "AF_INET6" : "???", 
       family); 

     // for an AF_INET* interface addresses, display the address 
     if(family == AF_INET || family == AF_INET6) { 

      char host[NI_MAXHOST]; 

      if((gai_err = getnameinfo(ifa->ifa_addr, 
         (family == AF_INET) ? sizeof(struct sockaddr_in) : 
               sizeof(struct sockaddr_in6), 
         host, NI_MAXHOST, 
         NULL, 0, NI_NUMERICHOST)) != 0) { 
       fprintf(stderr, "getnameinfo: %s\n", gai_strerror(gai_err)); 
      } 

      printf("\t\t address: <%s>\n", host); 
     } 
    } 

    freeifaddrs(ifaddr); 
    return SUCCESS; 

をしかし、私は、私がクライアントに接続できる(プリント)、適切なIPアドレスが返されますことを確認することができますか? 192.168.102:私は、サーバーだけ192.168.8.102またはIPv6 :: FFFFで提供されて試験した場合

lo0  ??? (18) 
lo0  AF_INET (2) 
     address: <127.0.0.1> 
lo0  AF_INET6 (30) 
     address: <::1> 
lo0  AF_INET6 (30) 
     address: <fe80::1%lo0> 
gif0  ??? (18) 
stf0  ??? (18) 
en0  ??? (18) 
en0  AF_INET6 (30) 
     address: <fe80::1088:e458:89a7:7ee9%en0> 
en0  AF_INET (2) 
     address: <192.168.8.102> 
en1  ??? (18) 
bridge0 ??? (18) 
p2p0  ??? (18) 
awdl0 ??? (18) 
awdl0 AF_INET6 (30) 
     address: <fe80::dce1:4eff:fef8:f3bd%awdl0> 
utun0 ??? (18) 
utun0 AF_INET6 (30) 
     address: <fe80::695f:8478:f380:9efb%utun0> 

私は、このような結果を持っています。しかし、2番目のen0 AF_INET6 IPアドレスfe80 :: 1088:e458:89a7:7ee9。異なるIPアドレスとインターフェース(en0ではなくeth0など)を持つ別のコンピュータでこのプログラムを実行すると、正しいIPアドレスを返すことができるようにするにはどうすればよいですか?それはクライアント側のプログラムから接続できますか? enter image description here

+0

https://en.wikipedia.org/wiki/IPv6_address#Link-local_addresses_and_zone_indices ??? –

答えて

0

どのシステムでも異なるネットワークとアドレスを持つ複数のインターフェイスを持つことはできません。ルートバックでさえ、システムへのルートと同じである必要はありません。

クライアントは、クライアントとサーバーの間のどこかのNATのために、別のアドレスとポートに接続する必要があります。

IP_PKTINFOソケットオプションを使用してrecvmsgからアドレスを取得すると、メッセージの宛先となったアドレスを確認できますが、ネットワークレベルで変換されている可能性があります。

+0

しかし、ネットワークアプリには、クライアントアプリのIPアドレスとポート番号のユーザーがサーバーに接続するために入力する方法は? –

関連する問題