HOSTENT 結構 (winsock.h)
主機實體結構是由函式用來儲存指定主機的相關信息,例如主機名、IPv4 位址等等。 應用程式不應該嘗試修改此結構,或釋放其任何元件。 此外,每個線程只會配置一個 主機實體 結構的複本,因此應用程式應該先複製它所需的任何資訊,再發出任何其他 Windows 套接字 API 呼叫。
語法
typedef struct hostent {
char *h_name;
char **h_aliases;
short h_addrtype;
short h_length;
char **h_addr_list;
} HOSTENT, *PHOSTENT, *LPHOSTENT;
成員
h_name
主機 (計算機) 的官方名稱。 如果使用 DNS 或類似的解析系統,則會是導致伺服器傳回回復的完整功能變數名稱 (FQDN) 。 如果使用本機主機檔案,則它是IPv4位址之後的第一個專案。
h_aliases
以 NULL 結尾的替代名稱陣列。
h_addrtype
要傳回的地址類型。
h_length
每個地址的長度,以位元組為單位。
h_addr_list
主機的 NULL 終止地址清單。 位址會以網路位元組順序傳回。 宏 h_addr 定義為 h_addr_list[0]
與舊版軟體相容。
備註
gethostbyaddr 和 gethostbyname 函式會傳回主機實體結構的指標,這是 Windows Sockets 所配置的結構。 hostent 結構包含成功搜尋 name 參數中所指定主機的結果。
gethostbyaddr 和 gethostbyname 函式所傳回之 hostent 結構的記憶體是由 Winsock DLL 從線程本機記憶體內部配置。 不論線程上呼叫 gethostbyaddr 或 gethostbyname 函式的次數為何,都只會配置及使用單一主機實體結構。 如果要對相同線程上的 gethostbyaddr 或 gethostbyname 函式進行其他呼叫,則必須將傳回的 hostent 結構複製到應用程式緩衝區。 否則,傳回值將會由相同線程上的後續 gethostbyaddr 或 gethostbyname 呼叫覆寫。 當線程結束時,Winsock DLL 會釋放配置給傳回 之主機實體 結構的內部記憶體。
應用程式不應該嘗試釋放傳回 的主機實體 結構所使用的記憶體。 應用程式絕對不能嘗試修改此結構,或釋放其任何元件。 此外,每個線程只會配置此結構的一個複本,因此應用程式應該先複製它所需的任何資訊,再對 gethostbyaddr 或 gethostbyname 發出任何其他函數調用。
範例
下列範例示範搭配 gethostbyname 函式使用 hostent 結構。
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
// Need to link with Ws2_32.lib
#pragma comment(lib, "ws2_32.lib")
int main(int argc, char **argv)
{
//-----------------------------------------
// Declare and initialize variables
WSADATA wsaData;
int iResult;
DWORD dwError;
int i = 0;
struct hostent *remoteHost;
char *host_name;
struct in_addr addr;
char **pAlias;
// Validate the parameters
if (argc != 2) {
printf("usage: %s ipv4address\n", argv[0]);
printf(" or\n");
printf(" %s hostname\n", argv[0]);
printf(" to return the host\n");
printf(" %s 127.0.0.1\n", argv[0]);
printf(" to return the IP addresses for a host\n");
printf(" %s www.contoso.com\n", argv[0]);
return 1;
}
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed: %d\n", iResult);
return 1;
}
host_name = argv[1];
// If the user input is an alpha name for the host, use gethostbyname()
// If not, get host by addr (assume IPv4)
if (isalpha(host_name[0])) { /* host address is a name */
printf("Calling gethostbyname with %s\n", host_name);
remoteHost = gethostbyname(host_name);
} else {
printf("Calling gethostbyaddr with %s\n", host_name);
addr.s_addr = inet_addr(host_name);
if (addr.s_addr == INADDR_NONE) {
printf("The IPv4 address entered must be a legal address\n");
return 1;
} else
remoteHost = gethostbyaddr((char *) &addr, 4, AF_INET);
}
if (remoteHost == NULL) {
dwError = WSAGetLastError();
if (dwError != 0) {
if (dwError == WSAHOST_NOT_FOUND) {
printf("Host not found\n");
return 1;
} else if (dwError == WSANO_DATA) {
printf("No data record found\n");
return 1;
} else {
printf("Function failed with error: %ld\n", dwError);
return 1;
}
}
} else {
printf("Function returned:\n");
printf("\tOfficial name: %s\n", remoteHost->h_name);
for (pAlias = remoteHost->h_aliases; *pAlias != 0; pAlias++) {
printf("\tAlternate name #%d: %s\n", ++i, *pAlias);
}
printf("\tAddress type: ");
switch (remoteHost->h_addrtype) {
case AF_INET:
printf("AF_INET\n");
break;
case AF_INET6:
printf("AF_INET6\n");
break;
case AF_NETBIOS:
printf("AF_NETBIOS\n");
break;
default:
printf(" %d\n", remoteHost->h_addrtype);
break;
}
printf("\tAddress length: %d\n", remoteHost->h_length);
if (remoteHost->h_addrtype == AF_INET) {
while (remoteHost->h_addr_list[i] != 0) {
addr.s_addr = *(u_long *) remoteHost->h_addr_list[i++];
printf("\tIPv4 Address #%d: %s\n", i, inet_ntoa(addr));
}
} else if (remoteHost->h_addrtype == AF_INET6)
printf("\tRemotehost is an IPv6 address\n");
}
return 0;
}
規格需求
需求 | 值 |
---|---|
最低支援的用戶端 | Windows 2000 Professional [僅限傳統型應用程式] |
最低支援的伺服器 | Windows 2000 Server [僅限桌面應用程式] |
標頭 | winsock.h (包含 Winsock2.h) |