2013-03-12 84 views
1
std::cout << WebClient().Load(in.substr(2, in.length())); 

我做了一個WebClient的樂趣,你可以傳入一個字符串通過cin到通過std :: getline(cin,in);訪問違規神祕與gethostbyname?

我Load方法的起始部分:

std::string Load(std::string url) 
{ 
    WSADATA wsaData; 
    if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) { 
     return "WSAStartup failed.\n"; 
    } 
    SOCKET Socket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); 
    struct hostent *host; 
    host = gethostbyname(url.c_str()); 
    SOCKADDR_IN SockAddr; 
    SockAddr.sin_port=htons(80); 
    SockAddr.sin_family=AF_INET; 
    if(host != nullptr) 
    { 
     SockAddr.sin_addr.s_addr = *((unsigned long*)host->h_addr); 
    } 

因爲主機成爲nullptr(因此檢查它),但具有相同字符串,但在不同的傳遞,我會得到一個訪問衝突:Web客戶端()。加載(「www.google.ca」)它的工作原理。我試圖把c_str()放在substr'ed字符串的末尾,但沒有用處。

我仍然在學習這個怪癖,這是怎麼回事?我使用從

#include <http.h> 
#include <string> 
#include <winsock2.h> 
#include <windows.h> 
#include <iostream> 
#pragma comment(lib,"ws2_32.lib") 
+0

@hyde我在調試模式下查看參數var,它是「www.google.ca」,就像傳遞一個const字符串一樣 – 2013-03-12 05:06:11

+0

因此,'gethostbyname'返回nullptr,你說?在這種情況下你傳遞給它什麼,url的價值是什麼? – hyde 2013-03-12 05:09:16

+0

當gethostbyname返回nullptr時,由getline()檢索的字符串被傳遞給方法。如果它是一個常量字符串,它不會返回nullptr,但即使在調試模式下,它看起來沒有格式錯誤,gethostbyname也無法處理它? – 2013-03-12 05:11:01

回答

2

編寫我的評論作爲答案:您應該打印URL的方式,讓你看看是否有額外的字符,甚至空白。然後你應該檢查你使用的所有功能的錯誤代碼,如在這裏閱讀the documentation of gethostbyname。下方的功能的調試版本,並與您需要的error codes explained here

#include <cstring> 

std::string Load(std::string url) 
{ 
    WSADATA wsaData; 
    if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) { 
     return "WSAStartup failed.\n"; 
    } 
    SOCKET Socket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); 
    struct hostent *host; 
    std::cout << "Getting hostname for url as seen by gethostbyname: '" << url.c_str() << "', strlen=" << strlen(url.c_str()) << std::endl; 
    host = gethostbyname(url.c_str()); 
    if (host) { 
     std::cout << "got valid hostent as response" << std::endl; 
    } else { 
     std::cout << "gethostbyname WSAGetLastError=" << WSAGetLastError() << std::endl; 
     return "Invalid url.\n"; 
    } 
    SOCKADDR_IN SockAddr; 
    SockAddr.sin_port=htons(80); 
    SockAddr.sin_family=AF_INET; 
    if(host != nullptr) 
    { 
     SockAddr.sin_addr.s_addr = *((unsigned long*)host->h_addr); 
    } 

的原因猜測:從cin您的網址包含空格在裏面。

關於術語的說明:該地址字符串,它不是真正的URL,url必須在開始時有像http://的計劃。你在那裏有一個完全合格的域名的主機,因爲它也應該是,gethostbyname不理解網址。

3

標準庫,請檢查什麼在所傳遞的字符串值收到來自getline。當gethostbyname收到它時,它可能會變形。您可以通過使用WSAGetLastError來檢查它是否失敗(併成爲NULL)。查詢MSDN的gethostbyname的可能error codes

編輯:你說你有看似完全相同的參數。你能找到一種方法來證明這一點(對你自己)。也許裏面有隱形角色?一個新行\n,或者它可能使用不同的編碼?只是一些想法。