Получил локальное имя хоста, работая на windows, но не в Linux

Я написал программу для получения локального имени хоста. если это не очевидно, я имею в виду получить имя хоста локальной машины, подобное gethostname метод, чтобы не получить строку localhost

я использую getaddrinfo с NULL для имени хоста, а затем позвоните getnameinfo с первым адресом.

Он отлично работает на компьютерах с Windows и дает мне каноническое имя хоста, но в Linux он не смог дать мне имя локального хоста и дает мне :: для IPv6 или 0.0.0.0 для IPv4.

Обратите внимание, что я использую AI_PASSIVE флаг в getaddrinfoзначит, это дает мне не более двух адресов.

в getnameinfo если я использую NI_NAMEREQD это не удалось.

Я делаю это, потому что у меня есть сервер, иногда я хочу прослушать все интерфейсы, а иногда и определенный интерфейс, у меня уже есть addrinfo и я просто хочу получить имя хоста от него, если это возможно.

Как я могу заставить его работать на Linux?
я что-то пропустил?

Спасибо за любую помощь.

Вот мой код: (кросс-платформенный, Windows и Linux, просто скопируйте & прошлое)
Вы можете скомпилировать и запустить оба и увидеть разницу.

#include <iostream>

#ifdef WIN32

#ifdef UNICODE
#undef UNICODE /* don't want Unicode, to keep code compatibility */
#endif

#include <WS2tcpip.h>
#pragma comment(lib, "ws2_32.lib")
class CWSAInitializer{
public:
CWSAInitializer(){
WSADATA data;
WSAStartup(MAKEWORD(2,2),&data);
}
~CWSAInitializer(){
WSACleanup();
}
}autoInit;

#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#endif

const char* get_hostname(struct addrinfo* info, char buff[], int buff_len)
{
int addrlen = (int)info->ai_addrlen;
int res = getnameinfo(info->ai_addr, addrlen, buff, buff_len, NULL, 0, 0);
if(res){
return NULL;
}
return buff;
}

int main ()
{
char temp[100];
addrinfo *ai,hints;
memset(&hints,0,sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_NUMERICSERV;
hints.ai_flags |= AI_PASSIVE;

int res = getaddrinfo(NULL, "0", &hints, &ai);
if(res){
std::cerr<<gai_strerror(res)<<std::endl;
return -1;
}
std::cout<< get_hostname(ai,temp,100)<<std::endl;
freeaddrinfo(ai);

return 0;
}

РЕДАКТИРОВАТЬ

  1. Сервер также должен принимать клиента с других компьютеров, поэтому он не может сообщить о прослушивании :: или же 0.0.0.0,

  2. Я знаю, что могу исправить это так:

if(std::string("::") == hostname || std::string("0.0.0.0") == hostname)
gethostname(hostname,100)

  1. Я не хочу получать localhost как результат, если адрес 127.0.0.1 или же ::1,

1

Решение

getaddrinfo() возвращает заголовок списка struct addrinfo узлы.

Обходит этот список, используя struct addrinfoчлен ai_next найти адреса всех интерфейсов машины.

Чтобы получить что-то еще, кроме адресов подстановки не указать AI_PASSIVE флаг в подсказках пройден.


Обновите информацию о различных именах, присвоенных машине и / или адресам ее интерфейсов:

  1. Имя хозяина («имя хоста«) как отреагировал gethostname() является атрибутом для хоста. это настроен на хосте и не хранится ни в одной внешней базе данных. Это имя хоста по определению не связано к любому из имен, которые разрешают адреса возможных интерфейсов. Имя хоста может быть однако быть сконфигурировано чтобы соответствовать названию один из адресов (интерфейсов машины) разрешается в.

  2. Может быть более одного интерфейса, предоставленного машиной. Адрес каждого из этих интерфейсов должен соответствовать другому имени, которое, в свою очередь, также может отличаться от имени, возвращаемого gethostname() (см. 1. выше). Это относится ко всем типам интерфейсов, включая IPv4 и IPv6. Там и это виртуальный wildcard-адрес (0.0.0.0для IPv4), который позволяет программам связываться и слушать все интерфейсы (набранные здесь IPv4), которые предоставляет машина. Подстановочный знак имеет нет название.

Вывод из 1. и 2. это: Нет имени «… как [возвращено] gethostname (), но каноническое.«!

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]