如何获取服务器的主机名?

时间:2015-12-17 19:51:10

标签: c++ sockets server client host

我用C ++创建了一个服务器和客户端,我希望它们在同一网络上相互连接,但在不同的机器上运行。我目前正在使用以下代码来使服务器连接到网络:

#define HOST_PORT "27015"

WSADATA wsaData;
int status;
struct addrinfo * data;
struct addrinfo hints;

WSAStartup(MAKEWORD(2, 2), &wsaData);

ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_IP;
hints.ai_flags = AI_PASSIVE;

char hostname[1024];
hostname[1023] = '\0';
gethostname(hostname, 1023);

if (getaddrinfo(hostname, HOST_PORT, &hints, &data))
{
    std::cout << "Unable to translate host name to address\n";
    WSACleanup();

    return 1;
}

客户端尝试使用类似的代码进行连接:

#define DEFAULT_PORT "27015"

struct addrinfo hints;

ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;

char hostname[1024];
hostname[1023] = '\0';
gethostname(hostname, 1023);

struct addrinfo *result = NULL;
int iResult = getaddrinfo(hostname, DEFAULT_PORT, &hints, &result);

if (iResult != 0)
{
    std::cout << ("getaddrinfo failed with error: %d\n", iResult);
    WSACleanup();

    return false;
}

当客户端和服务器位于同一台计算机上时,这可以正常工作,但是当它们位于不同的计算机上时,如何允许它们进行连接?我希望在使用gettaddrinfo()时我需要客户端连接到相同的主机名,但是如何获取服务器的主机名? (例如,如果服务器上的hostname成为&#34; InsertNameHere&#34;,我如何允许客户端检测&#34; InsertNameHere&#34;并将其用作getaddrinfo()中的第一个参数?)

2 个答案:

答案 0 :(得分:1)

你的问题很常见,而且有几种方法。

手动配置

例如,您的服务器可能会找到它的IP4地址,将其打印到控制台,然后您以某种方式在客户端应用程序中手动指定该地址,例如作为命令行参数,或在某些配置文件中。

这是开发人员最友好,最不方便用户的方式。

服务发布

您的服务器可能会在启动时将自己注册到客户端可能阅读的某个位置。人们通常在企业Windows环境中实现此方法,其中Active Directory就是“某个地方”。如果是这种情况,请为您需要的WinSock API see this article

服务发现

或者,您可以自己实现发现机制,例如使用UDP广播。

在您的服务器中,侦听某个UDP端口,等待一些发现数据报,并使用一些“已发现的”数据报进行响应。

在您的客户端中,在启动时,将发现UDP数据报发送到该UDP端口号的广播地址。如果您的服务器在客户端所在的相同子网上运行,则客户端将收到“已发现的确定”消息[s]。如果只有一个响应,您知道有一个可访问的服务器,您可以立即连接。如果有多个响应,则可能意味着有多个服务器,您可以询问用户连接的位置。

这种方法相对难以正确实现(例如,UDP不提供保证交付,因此需要重试和超时),但它是最用户友好的方式。如果你玩过像Quake这样的旧局域网游戏,那就是他们发现服务器的方式。

我想添加您可以使用的第三方库,例如CollageReplicaNet,但是我没有亲身体验过这些库,可以不推荐任何一个。

答案 1 :(得分:0)

要连接到远程服务器,您需要获取它的IP地址或主机名。默认方法是手动将其作为参数传递或使用命名服务,如ZooKeeper(请参阅wiki

最简单,最好的方法是配置网络并使用DNS而不是直接IP(例如myserver1.mycompany.com:27015,其中27015是TCP端口)。