計算機科学のブログ

C - ソケットとネットワーキング - 127.0.0.0.1という場所はない - クライアント, IPアドレス, ホスト

Head First C ―頭とからだで覚えるCの基本David Griffiths(著)、 Dawn Griffiths(著)、 中田 秀基(監修)、 木下 哲也(翻訳)、 O’Reilly Media)の 11章(ソケットとネットワーキング - 127.0.0.0.1という場所はない)、p.494(コードマグネット)の解答を求めてみる。

Makefile

all: a.out
	./a.out index

a.out: main.c
	cc main.c

コード

main.c

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <stdbool.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netdb.h>

void error(char *msg)
{
    fprintf(stderr, "%s:%s\n", msg, strerror(errno));
    exit(1);
}
int open_socket(char *host, char *port)
{
    struct addrinfo *res;
    struct addrinfo hints;
    memset(&hints, 0, sizeof(hints));
    hints.ai_family = PF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    if (getaddrinfo(host, port, &hints, &res) == -1)
    {
        error("アドレスを解決できません。");
    }
    int d_sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
    if (d_sock == -1)
    {
        error("ソケットを開けません。");
    }
    int c = connect(d_sock, res->ai_addr, res->ai_addrlen);
    freeaddrinfo(res);
    if (c == -1)
    {
        error("ソケットに接続できません。");
    }
    return d_sock;
}
int say(int socket, char *s)
{
    int result = send(socket, s, strlen(s), 0);
    if (result == -1)
    {
        fprintf(stderr, "サーバーとの通信エラー:%s", strerror(errno));
    }
    return result;
}
int main(int argc, char *argv[])
{
    int d_sock = open_socket("www.example.com", "80");
    char buf[255];
    sprintf(buf, "GET /%s http/1.1\r\n", argv[1]);
    say(d_sock, buf);
    say(d_sock, "Host: www.example.com\r\n\r\n");
    char rec[256];
    int bytesRcvd = recv(d_sock, rec, 255, 0);
    while (bytesRcvd)
    {
        if (bytesRcvd == -1)
        {
            error("サーバーから読み込みません。");
        }
        rec[bytesRcvd] = '\0';
        printf("%s", rec);
        bytesRcvd = recv(d_sock, rec, 255, 0);
    }
    close(d_sock);
}

入出力結果(Terminal, Zsh)

% make
cc main.c
./a.out index
%