Я написал программу для получения имени локального хоста. если это не очевидно, я имею в виду получить имя хоста локальной машины, аналогичное методу 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;
}
ИЗМЕНИТЬ
Сервер также должен принимать клиентов с других машин, поэтому он не может сообщить о прослушивании
::
или0.0.0.0
.Я знаю, что могу исправить это следующим образом:
if(std::string("::") == hostname || std::string("0.0.0.0") == hostname)
gethostname(hostname,100)
- Я не хочу получать в результате
localhost
, если только адрес не127.0.0.1
или::1
.