Как я могу получить IP-адрес моей серверной программы? - PullRequest
3 голосов
/ 23 марта 2010

Этот вопрос относится к другому вопросу, который я только что опубликовал . Я готовлюсь к простому рабочему проекту и пытаюсь ознакомиться с основами программирования сокетов в среде разработки Unix. На данный момент у меня есть некоторый базовый серверный код и настройка клиентского кода для связи. В настоящее время мой клиентский код успешно подключается к коду сервера и серверный код отправляет ему тестовое сообщение, после чего оба завершаются. Отлично! Это именно то, чего я хотел достичь. Сейчас я играю с функциями, используемыми для получения информации о двух средах (сервер и клиент). Я хотел бы получить IP-адрес моей серверной программы. Вот код, который я сейчас должен сделать, но он не работает ...

int sockfd;
unsigned int len;
socklen_t sin_size;
char msg[]="test message";
char buf[MAXLEN];
int st, rv;
struct addrinfo hints, *serverinfo, *p; 
struct sockaddr_storage client;
char s[INET6_ADDRSTRLEN];
char ip[INET6_ADDRSTRLEN];

//zero struct   
memset(&hints,0,sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;

//get the server info
if((rv = getaddrinfo(NULL, SERVERPORT, &hints, &serverinfo ) != 0)){
  perror("getaddrinfo");
  exit(-1);
}

// loop through all the results and bind to the first we can
for( p = serverinfo; p != NULL; p = p->ai_next)
{
  //Setup the socket
  if( (sockfd = socket( p->ai_family, p->ai_socktype, p->ai_protocol )) == -1 )
  {
    perror("socket");
    continue;
  }

  //Associate a socket id with an address to which other processes can connect
  if(bind(sockfd, p->ai_addr, p->ai_addrlen) == -1){
    close(sockfd);
    perror("bind");
    continue;
  }

  break;
}

if( p == NULL ){
  perror("Fail to bind");
}

inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr), s, sizeof(s));
printf("Server has TCP Port %s and IP Address %s\n", SERVERPORT, s);

и вывод для IP всегда пуст ...

server has TCP Port 22513 and IP Address ::

есть идеи для чего я скучаю?

Заранее спасибо за помощь! сначала это действительно сложно.

Ответы [ 2 ]

2 голосов
/ 23 марта 2010

Ваш сокет, вероятно, прослушивает все доступные интерфейсы / адреса. «::» является сокращением для адреса IPv6 «0: 0: 0: 0: 0: 0: 0: 0», что означает, что адрес не указан.

Вероятно, это потому, что вы запрашиваете у getaddrinfo () addrinfo для прослушивания любого адреса, и любой протокол, поддерживающий потоки и IPv6 с неопределенным адресом, появляется первым. Я немного не уверен в этом, хотя ...

0 голосов
/ 23 марта 2010

Похоже, что ваш код работает правильно, как написано, но, вероятно, не так, как ожидалось / задумано.IP-адрес, который вы печатаете, является правильным, поскольку вы привязываетесь ко всем доступным интерфейсам, поэтому сервер сможет принимать входящие TCP-соединения через любой сетевой интерфейс.getaddrinfo() приводит к следующему:

  • AF_UNSPEC для ai_family указывает, что вызывающая сторона должна принимать любое семейство адресов
  • SOCK_STREAM для ai_socktype указывает тип сокета потока
  • AI_PASSIVE, включенный в ai_flags , заставляет возвращаемый адрес быть подходящим для использования в привязке сокета для приема входящих соединений
    • поскольку имя узла равно NULL, для части IP-адреса структуры адреса сокета установлено значение INADDR_ANY для адреса IPv4 или IN6ADDR_ANY_INIT для адреса IPv6

Поскольку адреса IPv6 сортируются до адресов IPv4 при сортировке RFC 3484 , getaddrinfo() возвращает неопределенное значениеIPv6-адрес («0: 0: 0: 0: 0: 0: 0: 0»).

В вызовах inet_ntop() неуказанные адреса IPv6 могут быть представлены просто как «:: ".


Если вы ищете адрес, который может быть приравнен к имени хоста вашего сервера, вы можете получить имя хоста для машины через gethostname() и используйте его как имя узла в своем звонке на getaddrinfo().Поскольку вы указываете AF_UNSPEC для ai_family , допустимые описательные имена для nodename включают имена хостов.Если вы укажете конкретный IP-адрес вместо INADDR_ANY / IN6ADDR_ANY_INIT, сокет будет принимать только TCP-соединения через этот интерфейс.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...