2016-04-01 14 views
0

htmlページを取得するためにサイトを照会するC++コンソールアプリケーションを作成する必要があります。C++を使用してHTTP GETリクエストですべてのhtmlファイルを取得する方法は?

send(Socket, "GET /it/ricette/q-torte_forno_statico.html HTTP/1.1\r\nHost: worldrecipes.expo2015.org/\r\nConnection: close\r\n\r\n", strlen("GET /it/ricette/q-torte_forno_statico.html HTTP/1.1\r\nHost: worldrecipes.expo2015.org\r\nConnection: close\r\n\r\n"), 0); 
    char buffer[1000000]; 
    int nDataLength; 
    while ((nDataLength = recv(Socket, buffer, 1000000, 0)) > 0) { 
     int i = 0; 
     while (buffer[i] >= 32 || buffer[i] == '\n' || buffer[i] == '\r') {   
       cout << buffer[i]; 
       i += 1; 
      } 
     } 

それは私にエラーを与えるものではありませんが、私は表示されません:私は、URLでそれを照会したときに、私はhtmlファイルを参照してくださいので、私はこのコードを使用しているため

サイトは静的です全体のHTMLページと私が呼び出すたびに私は別の答えを得る要求を送信する...なぜ?

+1

HTTP仕様([RFC 2616](HTTPSを読みます.ietf.org/html/rfc2616)、およびより新しいRFC 7230-7235)。あなたが示したことは、有効な実装に近いものではありません。応答ヘッダーの終わりを示す '\ r \ n \ r \ n'シーケンスが出現するまで、ソケットから読み取らなければなりません。応答ヘッダーのフォーマットを判別するためには、受信したヘッダーを解析する必要がありますそのボディをその転送エンコーディングに従って読み込みます。 'Content-Length'、' Transfer-Encoding'、 'Content-Type'ヘッダを考慮する必要があります。詳細は、RFC 2616セクション4.4を参照してください。 –

+1

HTTPは手で実装するのは簡単ではありませんが、それには多くの規則とセマンティクスがあります。これを処理するより良い方法は、HTTPを手動で実装しないことです。 [libcurl](https://curl.haxx.se/libcurl/)のような既存のHTTPライブラリを代わりに使用してください。 –

+0

@RemyLebeau私はlibcurlがおそらくこのコードより優れていることを知っていますが、私はこのコードを使用する必要があります。今問題を解決しますが...ページが私に戻りますが、バッファはすべてのHTMLコードを入れるのに十分ではないので、*バッファのサイズの問題を解決する方法を知っていますか?>私の問題は:私はビジュアルスタジオのソケットの初期化に関するエラーを返すサイズを増やすとき。 –

答えて

0

このコードは、サブページではなくインデックスページworldrecipes.expo2015.orgでのみ動作するようです。 HTMLの解析と処理のために、より高度なWebブラウザコントロールをビジュアルスタジオで見ることができます。ここでは同様

:ここhttp://www.codeproject.com/Articles/3365/Embed-an-HTML-control-in-your-own-window-using-plahttps://msdn.microsoft.com/en-us/library/aa752046(v=vs.85).aspx 、ここで:http://www.codeproject.com/Articles/3919/Using-the-WebBrowser-control-simplified

例のコード://ツール:

#include <windows.h> 
#include <string> 
#include <stdio.h> 

using std::string; 

#pragma comment(lib,"ws2_32.lib") 


HINSTANCE hInst; 
WSADATA wsaData; 
void mParseUrl(char *mUrl, string &serverName, string &filepath, string &filename); 
SOCKET connectToServer(char *szServerName, WORD portNum); 
int getHeaderLength(char *content); 
char *readUrl2(char *szUrl, long &bytesReturnedOut, char **headerOut); 


int main() 
{ 
    const int bufLen = 1024; 
    char *szUrl = "http://worldrecipes.expo2015.org/it/ricette/q-torte_forno_statico.html"; 
    long fileSize; 
    char *memBuffer, *headerBuffer; 
    FILE *fp; 

    memBuffer = headerBuffer = NULL; 

    if (WSAStartup(0x101, &wsaData) != 0) 
     return -1; 


    memBuffer = readUrl2(szUrl, fileSize, &headerBuffer); 
    printf("returned from readUrl\n"); 
    printf("data returned:\n%s", memBuffer); 
    if (fileSize != 0) 
    { 
     printf("Got some data\n"); 
     fp = fopen("downloaded.file", "wb"); 
     fwrite(memBuffer, 1, fileSize, fp); 
     fclose(fp); 
//  SetDlgItemText(hwndDlg, IDC_EDIT4, headerBuffer); 
//  SetDlgItemText(hwndDlg, IDC_EDIT5, memBuffer); 
     delete(memBuffer); 
     delete(headerBuffer); 
    } 

    WSACleanup(); 
    return 0; 
} 


void mParseUrl(char *mUrl, string &serverName, string &filepath, string &filename) 
{ 
    string::size_type n; 
    string url = mUrl; 

    if (url.substr(0,7) == "http://") 
     url.erase(0,7); 

    if (url.substr(0,8) == "https://") 
     url.erase(0,8); 

    n = url.find('/'); 
    if (n != string::npos) 
    { 
     serverName = url.substr(0,n); 
     filepath = url.substr(n); 
     n = filepath.rfind('/'); 
     filename = filepath.substr(n+1); 
    } 

    else 
    { 
     serverName = url; 
     filepath = "/"; 
     filename = ""; 
    } 
} 

SOCKET connectToServer(char *szServerName, WORD portNum) 
{ 
    struct hostent *hp; 
    unsigned int addr; 
    struct sockaddr_in server; 
    SOCKET conn; 

    conn = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 
    if (conn == INVALID_SOCKET) 
     return NULL; 

    if(inet_addr(szServerName)==INADDR_NONE) 
    { 
     hp=gethostbyname(szServerName); 
    } 
    else 
    { 
     addr=inet_addr(szServerName); 
     hp=gethostbyaddr((char*)&addr,sizeof(addr),AF_INET); 
    } 

    if(hp==NULL) 
    { 
     closesocket(conn); 
     return NULL; 
    } 

    server.sin_addr.s_addr=*((unsigned long*)hp->h_addr); 
    server.sin_family=AF_INET; 
    server.sin_port=htons(portNum); 
    if(connect(conn,(struct sockaddr*)&server,sizeof(server))) 
    { 
     closesocket(conn); 
     return NULL; 
    } 
    return conn; 
} 

int getHeaderLength(char *content) 
{ 
    const char *srchStr1 = "\r\n\r\n", *srchStr2 = "\n\r\n\r"; 
    char *findPos; 
    int ofset = -1; 

    findPos = strstr(content, srchStr1); 
    if (findPos != NULL) 
    { 
     ofset = findPos - content; 
     ofset += strlen(srchStr1); 
    } 

    else 
    { 
     findPos = strstr(content, srchStr2); 
     if (findPos != NULL) 
     { 
      ofset = findPos - content; 
      ofset += strlen(srchStr2); 
     } 
    } 
    return ofset; 
} 

char *readUrl2(char *szUrl, long &bytesReturnedOut, char **headerOut) 
{ 
    const int bufSize = 512; 
    char readBuffer[bufSize], sendBuffer[bufSize], tmpBuffer[bufSize]; 
    char *tmpResult=NULL, *result; 
    SOCKET conn; 
    string server, filepath, filename; 
    long totalBytesRead, thisReadSize, headerLen; 

    mParseUrl(szUrl, server, filepath, filename); 

    ///////////// step 1, connect ////////////////////// 
    conn = connectToServer((char*)server.c_str(), 80); 

    ///////////// step 2, send GET request ///////////// 
    sprintf(tmpBuffer, "GET %s HTTP/1.0", filepath.c_str()); 
    strcpy(sendBuffer, tmpBuffer); 
    strcat(sendBuffer, "\r\n"); 
    sprintf(tmpBuffer, "Host: %s", server.c_str()); 
    strcat(sendBuffer, tmpBuffer); 
    strcat(sendBuffer, "\r\n"); 
    strcat(sendBuffer, "\r\n"); 
    send(conn, sendBuffer, strlen(sendBuffer), 0); 

// SetWindowText(edit3Hwnd, sendBuffer); 
    printf("Buffer being sent:\n%s", sendBuffer); 

    ///////////// step 3 - get received bytes //////////////// 
    // Receive until the peer closes the connection 
    totalBytesRead = 0; 
    while(1) 
    { 
     memset(readBuffer, 0, bufSize); 
     thisReadSize = recv (conn, readBuffer, bufSize, 0); 

     if (thisReadSize <= 0) 
      break; 

     tmpResult = (char*)realloc(tmpResult, thisReadSize+totalBytesRead); 

     memcpy(tmpResult+totalBytesRead, readBuffer, thisReadSize); 
     totalBytesRead += thisReadSize; 
    } 

    headerLen = getHeaderLength(tmpResult); 
    long contenLen = totalBytesRead-headerLen; 
    result = new char[contenLen+1]; 
    memcpy(result, tmpResult+headerLen, contenLen); 
    result[contenLen] = 0x0; 
    char *myTmp; 

    myTmp = new char[headerLen+1]; 
    strncpy(myTmp, tmpResult, headerLen); 
    myTmp[headerLen] = NULL; 
    delete(tmpResult); 
    *headerOut = myTmp; 

    bytesReturnedOut = contenLen; 
    closesocket(conn); 
    return(result); 
} 

enter image description here

+0

サブページが動作します'GET /'を 'GET/desiredpage'に置き換えてください。 301はHTTPリダイレクトです。'Location'値を抽出し、指定されたURLに新しい要求を送る必要があります。 –

+0

また、このコードは、OPのコードと同じバッファオーバーフローエラーが発生します。 'while'ループは' i

関連する問題