毛のはえたようなもの

インターネット的なものをつらつらとかきつらねる。

ネットワークプログラミング課題2-C++版

前日の記事のC言語のものを無駄にc++に書き直す。

#include <iostream>
#include <string>
#include <cerrno>
#include <list>
#include <sstream>

#include <arpa/inet.h>
#include <boost/xpressive/xpressive.hpp>

using namespace std;

class WebServer{
public:
    WebServer();
    ~WebServer();
    void Start();
private:
    int serverPort;
    int socket1;
    list<string> split(string str, string delim);
    void err_check(int response, string function_name);
};

WebServer::WebServer(){
    this->serverPort = 5555;
    this->socket1 = 0;
}

WebServer::~WebServer(){
    close(this->socket1);
}

// Start new conection and listen
void WebServer::Start(){
    this->socket1 = socket(AF_INET, SOCK_STREAM, 0);
    err_check(this->socket1, "socket");

    struct sockaddr_in server_addr = {};
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr= INADDR_ANY;
    server_addr.sin_port = htons(this->serverPort);

    err_check( bind(this->socket1,(struct sockaddr *)&server_addr,sizeof(server_addr)),"bind");

    //listen
    err_check(listen(this->socket1,16) ,"listen");
    
    while(true){
        int socket2 = 0;
        int IPadd_len = 16;
        struct sockaddr_in IPaddr;
        socket2 = accept(this->socket1,(struct sockaddr *)&IPaddr,(socklen_t *)&IPadd_len);
        err_check(socket2,"socket2");
    
        //recv
        ssize_t recv_ok;
        int data_size = 1000;
        char data_from_cliant[1000]="";
        recv_ok = recv(socket2, data_from_cliant, data_size, 0);
        err_check(recv_ok,"recv");
        string rcv_data(data_from_cliant);
    
        string path ="";
        list<string> line = split(rcv_data,"\n");
        list<string>::iterator iter = line.begin();
        
        while(iter != line.end()){
            if((*iter).find("GET")==0){
                path = *iter;
            }
            iter++;
        }

        ostringstream stm;
        stm << ntohs(IPaddr.sin_port);
        string cliantPort= stm.str();
        string html =
            "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01Transitional//EN\"><html><head></head><body>path::: "
            + path +
            " <br />IP::: "
            + inet_ntoa(IPaddr.sin_addr)
            +"<br />PORT::: "
            +  cliantPort
            +" <br /></body></html>\n";
 
        //send
        ssize_t send_ok;
        char send_char[1000] = "";
        strcpy(send_char,html.c_str());
        send_ok = send(socket2,send_char, html.size(), 0);
        err_check(send_ok,"send");
        //close
        close(socket2);
    }
}

//  error
void WebServer::err_check(int response, string function_name){
    if(-1 == response){
        cout << function_name << endl;
        perror("");
        exit(1);
    }
}

list<string> WebServer::split(string str, string delim){
    list<string> result;
    int cutAt;
    while( (cutAt = str.find_first_of(delim)) != str.npos ){
        if(cutAt > 0){
            result.push_back(str.substr(0, cutAt));
        }
        str = str.substr(cutAt + 1);
    }
    if(str.length() > 0){
        result.push_back(str);
    }
return result;
}

int main(int argc , char* argv[]){

    WebServer* newServer;
    newServer = new WebServer();
    newServer->Start();
    
    return 0;
}

いや、CよりC++のほうは正規表現が使えるときいたので。
正規表現ライブラリ boost::xpressive を使う - 日記を書く [・w・] はやみずさん
上を参考にboostをインストール。いやあ、タイミングよく記事をかいてくれる、さすが師匠wwwwつかえる

書きあがったらUPします。