1

UNIX ソケットを使用して HTTP クライアントを作成しています (宿題の一環として)。私は現在、特定の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ただし、 「google.com」など、IP ではないものになるように変更したいと考えています。を使用してこれを行う方法を理解しようとしてきましたが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 のドキュメントはひどいものです。

4

1 に答える 1

2

あなたが望むのは多分getaddrinfo(3)です:

#include <sys/socket.h>
#include <netdb.h>

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) &lt; 0) {
                goto out;
        }
        /* now try them all */
        for (const struct addrinfo *ai = aires;
             ai != NULL &&
                     ((s = socket(ai->ai_family, ai->ai_socktype, 0)) &lt; 0 ||
                      connect(s, ai->ai_addr, ai->ai_addrlen) &lt; 0);
             close(s), s = -1, ai = ai->ai_next);

out:
        freeaddrinfo(aires);
        return s;
}

このバージョンは、ホスト/ポートのペアからソケットを取得します。また、ホストには IP アドレス、ポートにはサービス文字列を使用します。ただし、問題のホストには既に接続されています。

于 2013-02-22T06:32:55.780 に答える