2014-10-10 58 views
0

我正在尝试使用c中的套接字构建HTTP请求。 所以,为了将套接字导航到正确的站点ip。 我需要获得该网站的IP。 我已经设法获得主机IP,但并不总是工作。 以下代码获取主机IP:如何使用c获取网站ip地址

host = gethostbyname(host_name); 
if (host != NULL) { 
    memcpy(&inp, host->h_addr_list[0], host->h_length); 
    sprintf(ip, "%s", inet_ntoa(inp)); 
} 

但是,这并不总是可行的,例如,如果我想套接字发送到stackoverflow.com和得到他的HTML content.I使用该代码输出功率为: “198.252.206.16”。 如果你输入该IP,你可以看到它是一个错误的IP,那么我该怎么办? 请帮忙。

P.S,这一切都是我的代码:

#include <stdio.h> 
#include <signal.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netdb.h> 
#include <netinet/in.h> 
#include <unistd.h> 
#include <string.h> 
#include <stdlib.h> 
#include <arpa/inet.h> 
#include <errno.h> 
#include <assert.h> 

int main(int argc, char **argv) { 

    if (argc < 2) { 
     fprintf(stderr, "usage: %s domain_name\nE.g. %s www.yahoo.com/lalal.html\n", argv[0], argv[0]); 
     return(0); 
    } 

struct protoent *pr; 
struct in_addr inp; 
int x = 1; 
int ret; 
char buf[4192]; 
char ip[16]; 
struct hostent *host; 
int sock, bytes_recieved; 
struct sockaddr_in server_addr; 

char url[strlen(argv[1])]; 
strcpy(url,argv[1]); 
char *index_page = strstr(argv[1], "/"); 
char *host_name = strtok(url,"/"); 
char message[4000]; 
sprintf(message,"GET %s HTTP/1.1\r\nHost: %s\r\n\r\n",index_page,host_name); 
printf("%s",message); 

host = gethostbyname(host_name); 
if (host != NULL) { 
    memcpy(&inp, host->h_addr_list[0], host->h_length); 
    sprintf(ip, "%s", inet_ntoa(inp)); 
} 
else { 
    printf("ERROR - Host ip was not found.\n\n"); 
    exit(1); 
} 

printf("%s\n",ip); 

pr = getprotobyname("tcp"); 
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { 
    perror("Socket"); 
    exit(1); 
} 
printf("%s\n",message); 
server_addr.sin_family = AF_INET;  
server_addr.sin_port = htons(80); 
server_addr.sin_addr = *((struct in_addr *)host->h_addr); 
bzero(&(server_addr.sin_zero),8); 

if (connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) { 
    perror("Connect"); 
    exit(1); 
} 

write(sock, message, strlen(message)); 

while ((ret = read(sock, buf, 4192)) != 0) { 
    buf[ret]='\0'; 
    fwrite(buf, ret, sizeof(char), stdout); 
    x++; 
} 

if (close(sock) == -1) 
    printf("Close socket error\n"); 

return 0; 

}

+2

当我做'NSLOOKUP 198.252.206.16',我得到'stackoverflow.com'。所以我害怕我不能“看到它是一个错误的IP”。 – indiv 2014-10-10 18:22:45

+0

你是什么意思“我想发送套接字到stackoverflow.com”? – 2014-10-10 18:28:15

+0

@indiv如果你输入那个发送你到STACKEXCHANGE站点 的IP,并且写着:“找不到198.252.206.16” – user3774164 2014-10-10 18:56:00

回答

1

StackExchange托管在同一台服务器上的多个站点。 198.252.206.16是该服务器的IP地址,这是连接套接字所需的正确IP地址。

从驻留在共享服务器上的站点请求HTTP资源时,必须提供HTTP Host标头来指定站点的主机名,以便服务器知道您尝试访问的站点。

例如,如果你去http://198.252.206.16,请求是这样的:

(connect to 198.252.206.16) 

GET/HTTP 1.1 
Host: 198.252.206.16 
... 

如果你去http://www.stackoverflow.com,请求如下:

(connect to 198.252.206.16) 

GET/HTTP 1.1 
Host: www.stackoverflow.com 
... 

如果你去http://www.stackexchange.com,请求如下所示:

(connect to 198.252.206.16) 

GET/HTTP 1.1 
Host: www.stackexchange.com 
... 

注意它们都连接到相同的IP地址。

没有与198.252.206.16主机相关的网站,这就是为什么您会收到错误消息。

Host标头对于所有HTTP 1.1请求是必需的,对于HTTP 1.0请求是可选的(但是如果缺少Host标头,则在这种情况下HTTP 1.0请求将失败)。它专为支持共享服务器上的多个站点而设计。

+0

我知道你提到的每一件事。 我不知道,但我想我需要导航套接字到什么IP地址发送套接字,对不对? 如果没有,那么socket如何知道要进入哪个站点?顺便说一句,我已经做了你已经提到的,并且套接字只是不返回任何东西。 谢谢。 – user3774164 2014-10-10 19:21:51

+1

显然不是,或者你不会首先遇到你的问题。您显示的'gethostbyname()'结果对于StackOverflow是正确的,因此您不得发送正确的HTTP请求来访问StackOverflow与其他StackExchange站点。请显示您的实际HTTP请求代码。 – 2014-10-10 19:22:22

+0

这是我的HTTP请求: GET/questions/26305618/how-to-get-site-ip-address-using-c/26306431 HTTP/1.1 \ r \ n主机:www.stackoverflow.com \ r \ n \ r \ n – user3774164 2014-10-10 19:44:25