takada-atです。 Rubyでソケットをいじっていたら、同じものをC/C++でも書いてみたくなりました。 そこで、C++でもHTTPクライアントに挑戦してみました。C/C++はよくわからないので、変なコードになっていると思いますが、遠慮なくつっこみをいただけるとうれしいです。 (そもそもコードが長すぎる気がします。。)

#include <iostream>
#include <sstream>
#include <string>
#include <vector>

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

using namespace std;

class Httpc{
    int BUFF_LEN;
public:
    int port;
    int soc;
    Httpc(){
        BUFF_LEN = 256;
        port = 80;
    }
    vector<string> parse_url(string url){
        int p = url.find("://");
        string path;
        url = url.substr(p+3);
        p = url.find("/");
        if(p==string::npos){
            path = "/";
        }else{
            path = url.substr(p+1);
            url = url.substr(0,p);
        }
        //cout << "host:" << url << " path:" << path << endl;
        vector<string> r;
        r.push_back(url); r.push_back(path);
        return r;
    }
    void openc(string url){
        vector<string> urls = parse_url(url);
        hostent *host;
        sockaddr_in addrin;

        soc = socket(AF_INET, SOCK_STREAM, 0);
        string reqh;
        host = gethostbyname( (urls[0]).c_str() );
        memset(&addrin, 0 ,sizeof(addrin));
        addrin.sin_family = AF_INET;
        addrin.sin_addr.s_addr = *(in_addr_t*)host->h_addr;
        addrin.sin_port = htons(port);
        connect(soc, (sockaddr*)&addrin, sizeof(addrin));
        reqh = "GET "+ urls[1] +" HTTP/1.0\r\n";
        reqh += "HOST: "+ urls[0]+ "\r\n";
        reqh += "\r\n\r\n";
        //cout << reqh << endl;
        send(soc, reqh.c_str(), reqh.length(), 0);
    }
    void closec(){
        close(soc);
    }
    void print(string url){
        this->openc(url);
        char buff[1024];
        char hh[1024];
        char s[1024];
        int r = 1;
        int state = 0;
        int i=0, p;
        if(r<0){
            state = 3;
        }
        while(r>0){
            r = read(soc, buff, sizeof(buff));
            if(state==0){
                for(i=0;i<sizeof(buff);++i){
                    if(state==0){
                        if(buff[i]=='\r' && buff[i+1]=='\n'){
                            ++i;
                            state = 1;
                        }
                    }else if(state==1){
                        if(buff[i]=='\r' && buff[i+1]=='\n'){
                            state = 2;
                            p = i;
                            break;
                        }else{
                            state = 0;
                        }
                    }
                }
                if(state==2)
                    cout << buff+p+2 << endl;
            }else if(state==2){
                write(1,buff,r);
            }

        }
    }
};
int main(int argc, char *argv[]){
    Httpc c;
    c.print(argv[1]);
}