我有一些代碼使用BSD套接字從服務器抓取網頁並將其寫入文件。以下是處理所有文件I/O以及使用套接字進行寫入和讀取的代碼。需要注意的是_sockfd
是說話者和聽者之間的有效插座:不尋常的意外值插入到HTML頁面抓取
FILE* resultFile;
resultFile = fopen(resultFilename.c_str(), "w+");
if (resultFile != 0)
{
// Construct the request
std::stringstream requestBuilder("");
requestBuilder << "GET " << directory << " HTTP/1.1\r\nHOST:" << _hostname << "\r\n\r\n";
std::string request = requestBuilder.str();
// Prepare to read the file and write it out
int bufferSize(1024);
char buffer[bufferSize];
int bytesRead(1);
// Send request
int bytesWritten = write(_sockfd, request.c_str(), request.length());
if (bytesWritten < 0)
{
std::cout << "Error on initial request send" << std::endl;
return false;
}
// Read response
while (bytesRead > 0)
{
bzero(buffer, bufferSize);
bytesRead = read(_sockfd, buffer, bufferSize);
if (bytesRead < 0)
{
std::cout << "WebCrawler -> ERROR: Could not read properly from socket" << std::endl;
return false;
}
fputs(buffer, resultFile);
}
fclose(resultFile);
_socketUsed = true;
,我希望這個代碼產生的結果看起來像下面的代碼片段:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Serebii.net Pokédex - #089 Muk</title>
<meta name="GENERATOR" content="Arachnophilia 4.0">
<meta name="FORMATTER" content="Arachnophilia 4.0">
<meta name="keywords" content="Pokemon, Pokédex, Muk (Pokémon),Muk, Diamond, Pearl, Platinum, HeartGold, SoulSilver" />
<link rel="stylesheet" type="text/css" HREF="/style/dex.css">
</head>
<meta http-equiv="imagetoolbar" CONTENT="no">
<link rel="stylesheet" type="text/css" HREF="http://www.serebii.net/spp-temp.css">
<LINK REL="SHORTCUT ICON" HREF="http://www.serebii.net/favicon.ico">
<BODY ondragstart="return false" text=#000000 bottomMargin=0 bgcolor="#383838"
leftMargin=0 topMargin=0 rightMargin=0>
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%" height="1" background="http://www.serebii.net/BannerBg.jpg">
<tr>
但是,相反,它看起來是這樣的:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Serebii.net Pokédex - #089 Muk</title>
<meta name="GENERATOR" content="Arachnophilia 4.0">
<meta name="FORMATTER" content="Arachnophilia 4.0">
<meta name="keywords" content="Pokemon, PokÈdex, Muk (PokÈmon),Muk, Diamond, Pearl, Platinum, HeartGold, SoulSilver" />
<link rel="stylesheet" type="text/css" HREF="/style/dex.css">
</head>
8c1
<meta http-equiv="imagetoolbar" CONTENT="no">
<link rel="stylesheet" type="text/css" HREF="http://www.serebii.net/spp-temp.css">
<LINK REL="SHORTCUT ICON" HREF="http://www.serebii.net/favicon.ico">
<BODY ondragstart="return false" text=#000000 bottomMargin=0 bgcolor="#383838"
leftMargin=0 topMargin=0 rightMargin=0>
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%" height="1" background="http://www.serebii.net/BannerBg.jpg">
<tr>
正如你看到的,我的代碼以某種方式插入奇怪的字符(在這種情況下,「8C1」)到的結果。我想強調的是,這在整個HTML文檔中都會發生多次。爲簡潔起見,我僅僅將自己侷限於一個例子。我懷疑我可能會以某種方式濫用緩衝區,但到目前爲止我一直無法找到解決方案。
包括在我以前的努力,以解決我的問題在以下做題:
C Winsock programming: input garbage
Raw Sockets : Receiver printing garbage values
我還引用了以下頁面,以確保我在做C文件I/O正確(我習慣用C與fstream的工作++):
http://www.cprogramming.com/tutorial/cfileio.html
我對使用套接字的網絡編程非常缺乏經驗(正如你可能知道的那樣),並且我確信這是一個愚蠢的錯誤。對於那些比我更有經驗的人:即使你不能直接指出我的解決方案,請分享你對我可能犯錯的地方的看法。有時候,我們需要找到答案的只是一些放置良好的麪包屑。爲此,請告訴我是否顯示錯誤的代碼和/或您認爲代碼的另一部分可能更有用。
此外,這是我的第一個SO問題。請按照您認爲合適的方式對其進行評論,以確保我的未來問題更好,更適合網站。
****更新1 ****(馬克贖金的建議後更改的fputs到使用fwrite):
我改變fputs(buffer, resultFile);
到fwrite(buffer, 1, bytesRead, resultFile);
。我現在看到,在這種情況下使用更合適。
但是,我的問題依然存在。事實上,我發現在新代碼(和我的舊代碼)連續執行5次後,我在原始問題中錯誤地稱爲「垃圾」值的錯誤值每次都完全相同。他們根本不是隨機的。我改變了我的問題的標題,以更恰當地描述我的問題。
經過一番更多的討論後,我想補充說,在讀取產生與文件寫入相同的結果後,將buffer
打印到控制檯。
您已將此標籤標記爲「C」,但是......「std :: string」。不是C,這是C++(不管你使用C風格的IO)。 – 2012-08-14 21:50:35
這裏的問題沒有問題。你給出了代表你的問題的很好的一小段代碼,以及「我期待這一點,但我得到了這個」的輸出。真的不能要求更好。歡迎來到這個網站。 – 2012-08-14 21:59:07
@Jared Friese嘗試附加一個調試器,如gdb或VS.您可能想在每次讀取後查看'bytesRead'的值。看起來你有套接字編程,只是現在寫的二進制文件。祝你好運。 – MartyE 2012-08-14 23:10:02