2013-02-22 5 views
1

Я пишу HTTP-клиент, используя UNIX-сокеты (как часть домашнего задания). Я в настоящее время этот рабочий код для подключения к данному IP-адресу:Получение адреса IP и использование сокета для подключения к нему

int sockfd = socket(AF_INET, SOCK_STREAM, 0); 
char *server_address = "127.0.0.1"; 
struct sockaddr_in address; 
if (sockfd < 0) { 
    printf("Unable to open socket\n"); 
    exit(1); 
} 

// Try to connect to server_address on port PORT 
address.sin_family = AF_INET; 
address.sin_addr.s_addr = inet_addr(server_address); 
address.sin_port = htons(PORT); 

if (connect(sockfd, (struct sockaddr*) &address, sizeof(address)) < 0) { 
    printf("Unable to connect to host\n"); 
    exit(1); 
} 

Однако, теперь я хочу, чтобы изменить его так, чтобы server_address также может быть что-то, что не является IP, такие как «google.com». Я пытался выяснить, как это сделать, используя gethostbyname, но у меня проблемы.

Будет ли gethostbyname принимать как IP-адрес, так и адрес, например «google.com», и заставить его работать правильно? (или я должен сначала запустить и запустить регулярное выражение по адресу и сделать что-то еще, если это IP-адрес)?

Я попытался следующий код, чтобы попытаться получить его работу с чем-то вроде «google.com», но я получаю предупреждение warning: assignment makes integer from pointer without a cast

struct hostent *host_entity = gethostbyname(server_address); 
address.sin_addr.s_addr = host_entity->h_addr_list[0]; 

Я знаю, что я делаю-это неправильно, но Документация gethostbyname ужасна.

+0

'#include ' ' – ugoren

+3

тетсру (& address.sin_addr, host_entity-> h_addr_list [0], host_entity-> h_length);' –

+0

@BrianRoach, что сделал это! Если бы вы хотели написать это как ответ, я бы принял его. :) – Darthfett

ответ

2

То, что вы хотите, может быть getaddrinfo(3):

 
#include 
#include 

static int 
resolve(const char *host, const char *port) 
{ 
     struct addrinfo *aires; 
     struct addrinfo hints = {0}; 
     int s = -1; 

     hints.ai_family = AF_UNSPEC; 
     hints.ai_socktype = SOCK_STREAM; 
     hints.ai_flags = 0; 
#if defined AI_ADDRCONFIG 
     hints.ai_flags |= AI_ADDRCONFIG; 
#endif /* AI_ADDRCONFIG */ 
#if defined AI_V4MAPPED 
     hints.ai_flags |= AI_V4MAPPED; 
#endif /* AI_V4MAPPED */ 
     hints.ai_protocol = 0; 

     if (getaddrinfo(host, port, &hints, &aires) < 0) { 
       goto out; 
     } 
     /* now try them all */ 
     for (const struct addrinfo *ai = aires; 
      ai != NULL && 
        ((s = socket(ai->ai_family, ai->ai_socktype, 0)) < 0 || 
         connect(s, ai->ai_addr, ai->ai_addrlen) < 0); 
      close(s), s = -1, ai = ai->ai_next); 

out: 
     freeaddrinfo(aires); 
     return s; 
} 

Эта версия получает вас сокет от пары хост/порт. Он также принимает IP-адреса для хоста и служебных строк для порта. Тем не менее, он будет подключен к этому хосту.