GetPage wxWidgetsillä

Linkku 21.07.05 12:33

 Tekstiversio  Arvo: 8 (8 ääntä)  Äänestä: +  -
/*
    Ohjelman on tarkoitus demonstroida komentoriviohjelman tekoa,
    sockettien käyttöä ja komentoriviargumenttien parsimista wxWidgetsillä.

    Ohjelma siis kysyy palvelimelta tiedostoa "/", jolloin palvelin
    hyvässä tapauksessa palauttaa etusivun.

    Kääntäminen:
        g++ `wx-config --libs --cxxflags` getpage.cpp -o getpage
    Käyttö:
        ./getpage -h kiuas.net [-p 80]

    Manuaali:
        http://wxwidgets.org/manuals/2.6.1/wx_contents.html
    Socketit:
        http://wxwidgets.org/manuals/2.6.1/wx_wxsocketbase.html
    wxCmdLineParser:
        http://wxwidgets.org/manuals/2.6.1/wx_wxcmdlineparser.html

*/


/* getpage.cpp: */
#include <wx/wx.h>
#include <wx/socket.h>
#include <wx/cmdline.h>
#include <iostream>
#include <memory>
using namespace std;

class GetPage : public wxAppConsole
{
public:
    int OnRun();
    void OnInitCmdLine(wxCmdLineParser& parser);
    bool OnCmdLineParsed(wxCmdLineParser& parser);
    bool OnInit();
private:
    wxString m_host;
    long int m_port;
};

void print(wxString text) {
    cout << text.ToAscii() << endl;
}

#define err(x) cout << "Error: " << #x << endl;

bool GetPage::OnInit()
{
    /* omalla koneellani se on "2.6 (debug,Unicode,compiler with
       C++ ABI 102,wx containers,compatible with 2.4) */

    cout << "Build info: " << WX_BUILD_OPTIONS_SIGNATURE << endl;
    return wxAppConsole::OnInit();
}

void GetPage::OnInitCmdLine(wxCmdLineParser& parser)
{
    /* Lisää myös -h option, joten ei käytetä
       wxAppConsole::OnInitCmdLine(parser); */


    /* Asetetaan komentoriviargumentit */
    static const wxCmdLineEntryDesc cmdLineDesc[] = {
        { wxCMD_LINE_OPTION, wxT("h"), 0, wxT("osoite"), wxCMD_LINE_VAL_STRING,
            wxCMD_LINE_OPTION_MANDATORY /* pakollinen argumentti */ },
        { wxCMD_LINE_OPTION, wxT("p"), 0, wxT("käytettävä portti"),
            wxCMD_LINE_VAL_NUMBER },
        { wxCMD_LINE_NONE , 0, 0, 0, wxCMD_LINE_VAL_NONE, 0 }
    };

    parser.SetDesc(cmdLineDesc);
}

bool GetPage::OnCmdLineParsed(wxCmdLineParser& parser) {
    if(!parser.Found(wxT("h"), &m_host)) {
        return false;
    }

    if(!parser.Found(wxT("p"), &m_port)) {
        m_port = 80;
    }

    /* Tulisi asserttia, kun ei käytetä
      wxAppConsole::OnInitCmdLine(parser)-funktiota
      return wxAppConsole::OnCmdLineParsed(parser); */

    return true;
}

int GetPage::OnRun() {

    /* Asetukset.. */
    wxIPV4address addr;
    addr.Hostname(m_host);
    addr.Service(m_port);

    /* Luodaan uusi socketclient */
    auto_ptr<wxSocketClient> socket(new wxSocketClient());

    socket->Connect(addr);

    if (socket->IsConnected())
        print(wxT("Connected to ") + addr.IPAddress());
    else {
        print(wxT("Can not connect to ") + m_host);
        /* tarkistetaan errorit */
        switch(socket->LastError()) {
            case wxSOCKET_INVOP:
                err(wxSOCKET_INVOP);
                break;
            case wxSOCKET_IOERR:
                err(wxSOCKET_IOERR);
                break;
            case wxSOCKET_INVADDR:
                err(wxSOCKET_INVADDR);
                break;
            case wxSOCKET_INVSOCK:
                err(wxSOCKET_INVSOCK);
                break;
            case wxSOCKET_NOHOST:
                err(wxSOCKET_NOHOST);
                break;
            case wxSOCKET_INVPORT:
                err(wxSOCKET_INVPORT);
                break;
            case wxSOCKET_WOULDBLOCK:
                err(wxSOCKET_WOULDBLOCK);
                break;
            case wxSOCKET_TIMEDOUT:
                err(wxSOCKET_TIMEDOUT);
                break;
            case wxSOCKET_MEMERR:
                err(wxSOCKET_MEMERR);
                break;
            default:
                err(Unknown error);
        }
        return FALSE;
    }

    wxString request = wxT("GET / HTTP/1.1\r\nHost: ")+m_host+wxT("\r\nUse")
        +wxT("r-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.8)")
        +wxT(" Gecko/20050517 Firefox/1.0.4\r\n\r\n");

    print(request);

    // lähetetään pyyntö
    socket->Write(request.mb_str(), request.Length());

    char c = 0x00;
    wxString data;

    while( socket->IsConnected() && !socket->Error() )
    {
        // luetaan yksi tavu
        socket->Read(&c, 1);
        // liitetään se stringin perään
        data.Append(static_cast<wxChar>(c), 1);
    }

    // kun kaik on luettu tulostetaan se
    print(data);
    return TRUE;
}

// kerrotaan wxwidgetsille, että tästä luokasta luodaan istanssi
IMPLEMENT_APP_CONSOLE(GetPage)
 

Akiro 13:16 21.7.05 
Eikös wxwidgets ole tämä cross-platform GUI-kirjasto? Mitäs hyötyä siitä on komentorivisovelluksia tehtäessä?
Linkku 13:28 21.7.05 
Kuten esimerkistä huomaamme, wxWidgets sisältää myös monia muita apuluokkia kuin pelkät GUI-toiminnot. Kirjastosta löytyvät niin threadit, ftp-luokka kuin ZIP-tiedostojen käsittely. Täällä lista luokista.