如何使用c获取站点IP地址

时间:2014-10-10 18:15:56

标签: c sockets http ip

我正在尝试使用c中的套接字构建HTTP请求。 所以,为了将套接字导航到正确的站点ip。 我需要获取网站的IP。 我已经设法获得主机IP,但并不总是有效。 以下代码获取主机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内容。我使用此代码,输出为:" 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;

}

1 个答案:

答案 0 :(得分: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主机关联的网站,这就是您收到错误消息的原因。

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