2016-04-01 26 views
0

Ben html sayfası almak sırayla bir site sorgulamak bir C++ konsol uygulaması oluşturmak gerekir.Nasıl C++ kullanarak bir HTTP GET isteği ile tüm html dosyası nasıl alınır?

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; 
      } 
     } 

Bana herhangi bir hata vermez ama bana görünmüyor: Ben html dosyası bkz url sorgulandığında, bu yüzden ne zaman bu kodu kullanın çünkü

sitesi statik Tüm html sayfası ve aradığım her zaman farklı cevaplar aldığım isteği gönderdim ... neden?

+1

HTTP belirtimi ([RFC 2616] (https Oku .ietf.org/html/rfc2616) ve daha yeni RFC'ler 7230-7235). Gösterdiğin şey geçerli bir uygulama olmaya yakın bile değil. Eğer bir '\ r \ n karşılaşana kadar Yuva okumak zorunda \ r \ varsa o zaman, yanıt vücudun biçimini belirlemek için alınan başlıkları ayrıştırmak zorunda yanıt başlıkları sonunu belirten dizisi n' aktarım kodlamasına göre vücudu okumak. 'Content-Length',' Transfer-Encoding' ve 'Content-Type' başlıklarını hesaba katmalısınız. Detaylar için RFC 2616 Bölüm 4.4'e bakınız. –

+1

HTTP, elle uygulamak için önemsiz değildir, bunun için çok fazla kural ve anlam bilgisi vardır. Bunu işlemenin daha iyi bir yolu, HTTP'yi hiç manuel olarak uygulamamaktır. Böyle [libcurl] olarak yerine önceden var olan bir HTTP kitaplığı kullanın (https://curl.haxx.se/libcurl/), sizin için zor işi yapalım. –

+0

@RemyLebeau ben libcurl belki bu kodun daha iyi olduğunu biliyorum, ama bu kodu kullanmanız gerekir. Şimdi sorunu çözmek ama ... * tampon boyutunun sorunu çözmek için nasıl biliyor musunuz * bana ama tampona sayfa dönüş benim problemim böylece tüm html Kodunuzu> içermesi büyük yeterli olmadığı için : Ben boyutu Görsel stüdyo artırmak işlemi sırasında tek bir sabit uzunluk tampon içine tüm yanıtı alamaz .. –

cevap

0

Aşağıdaki kod yalnızca alt sayfalarda değil, worldrecipes.expo2015.org dizin sayfasında çalışır. HTML'yi ayrıştırmak ve işlemek için görsel stüdyo için daha gelişmiş web tarayıcısı denetimlerine bakmak isteyebilirsiniz.

burada gibi: Burada http://www.codeproject.com/Articles/3365/Embed-an-HTML-control-in-your-own-window-using-pla : Burada https://msdn.microsoft.com/en-us/library/aa752046(v=vs.85).aspx ve: http://www.codeproject.com/Articles/3919/Using-the-WebBrowser-control-simplified

Örnek kod: // araçları:

#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

Alt sayfalar sadece iyi, sadece gerektiği gibi GET/istenilen "GET /" ile değiştirin. 301 bir HTTP yönlendirmesidir.'Yer' değerini çıkarmanız ve belirtilen URL'ye yeni bir istek göndermeniz gerekir. –

+0

Ayrıca, bu kod, OP'nin koduyla aynı arabellek taşması hatasıyla karşı karşıyadır. 'While' döngüsünün' i

İlgili konular