2012-03-06 88 views
2

有是,隨着HTTP響應.png文件服務器:的boost :: ASIO文件發送

#include "server.h" 
string Server::header(int contentLength) 
{ 
    string h = 
    "HTTP/1.1 200 OK\n" 
    "Content-Length: " + boost::lexical_cast<string>(contentLength) + "\n" 
    "Content-Type: image/png;\n" 
    "Connection: close\n" 
    "\n"; 
    return h; 
} 
string Server::readMap(const string &filename) 
{ 
    ifstream file (filename.c_str(), ios::in|ios::binary); 
    string reply; 
    char buf[512]; 
    while (file.read(buf, sizeof(buf)).gcount() > 0) 
     reply.append(buf, file.gcount()); 
    return reply; 
} 
void Server::run(const string &filename, int port) 
{ 
    string data = readMap(filename); 
    try 
    { 
     boost::asio::io_service io_service; 
     tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), port)); 
     for (;;) 
     { 
      tcp::socket socket(io_service); 
      acceptor.accept(socket); 
      boost::asio::write(socket, boost::asio::buffer(header(data.size()))); 
      boost::asio::write(socket, boost::asio::buffer(data)); 
     } 
    } 
    catch (std::exception& e) 
    { 
     cerr << "exception: " << e.what() << endl; 
    } 
} 

每次發生錯誤:

例外:連接被對方​​復位

我可以在瀏覽器中看到圖像的某些部分,有時圖像幾乎完整,但不會出現錯誤。

如果我使用wget它看起來像

wget http://localhost:8089 
--2012-03-07 12:07:19-- http://localhost:8089/ 
Resolving localhost... 127.0.0.1 
Connecting to localhost|127.0.0.1|:8089... connected. 
HTTP request sent, awaiting response... 200 OK 
Length: 760032 (742K) [image/png] 
Saving to: `index.html' 

62% [========================================================>         ] 475,136  --.-K/s in 0.002s 

2012-03-07 12:07:19 (287 MB/s) - Read error at byte 475136/760032 (Connection reset by peer). Retrying. 

--2012-03-07 12:07:20-- (try: 2) http://localhost:8089/ 
Connecting to localhost|127.0.0.1|:8089... connected. 
HTTP request sent, awaiting response... 200 OK 
Length: 760032 (742K) [image/png] 
Saving to: `index.html' 

73% [==================================================================>       ] 557,056  --.-K/s in 0.001s 

... many failes and finally 

--2012-03-07 12:09:01-- (try: 9) http://localhost:8089/ 
Connecting to localhost|127.0.0.1|:8089... connected. 
HTTP request sent, awaiting response... 200 OK 
Length: 760032 (742K) [image/png] 
Saving to: `index.html' 

100%[===========================================================================================>] 760,032  --.-K/s in 0.001s 

任何想法如何解決呢?

回答

3

ASIO-docs中有幾個更完整的HTTP實現,包括靜態文件服務。一種方法是重用你的應用程序中的一些示例代碼。

在這種特定情況下,有一個在http://www.boost.org/doc/libs/1_49_0/doc/html/boost_asio/example/http/server/request_handler.cpp

std::ifstream is(full_path.c_str(), std::ios::in | std::ios::binary); 
    ... 
    char buf[512]; 
    while (is.read(buf, sizeof(buf)).gcount() > 0) 
    rep.content.append(buf, is.gcount()); 

該文檔還具有用於實際的異步HTTP的實現示例的如何正確地打開和緩衝文件的例子。 (我假設你使用boost :: asio來最終使它異步?)

+0

我已編輯源和問題。沒有什麼幫助( – spe 2012-03-07 08:22:12

+0

我完全不知道是什麼原因導致了這種情況,但它可能與開始回覆之前不等待請求有關 您應該儘可能少地執行HTTP協議的行解析,並等待,直到你收到一個雙重換行序列 除此之外,我真的不能看到任何明顯的做錯了,除了不正確的行終止(HTTP期望\ r \ n),但我懷疑這是你的原因問題,我假定文件在傳輸過程中沒有改變,當然, – Rawler 2012-03-07 09:13:46

+0

你很可能!你應該至少做一下HTTP協議的行解析,然後等到你收到一個double-newline-序列。 – spe 2012-03-07 09:34:21

1

您應該首先接收並解碼HTTP請求,並且只有在請求時才發送內容。瀏覽器有時也會請求其他資源;如果您發送意外事件,或者在發送請求之前發送它們,他們可能會感到不安。

你似乎也有一個錯誤的數據大小 - 你把data.size()-1在頭,然後發送所有的data。也許這是對readMap中的錯誤的部分解決方法,在您到達EOF後您會推送額外的字符。在閱讀之後但在推動角色之前檢查eof()會更好,或者通過讀取在不易出錯(和更高效的)的方式,如:

std::copy(std::istreambuf_iterator<char>(file), 
      std::istreambuf_iterator<char>(), 
      std::back_inserter(data)); 

另外,我看不出有任何理由載體複製到stringvector也可以轉換爲asio::buffer

+0

我不認爲這是原因。我只是試着用curl下載它(它不會給服務器發送任何意外的消息) spe $ curl http://craft.omg-team.org> img。png %總計%收到%Xferd平均速度時間時間時間當前 Dload上傳總花費左速度 65 1238k 65 817k 0 0 233k 0 0:00:05 0:00:03 0:00:02 243k curl :(56)接收失敗:連接重置由對端(抱歉格式化) – spe 2012-03-06 16:42:19

+0

我將檢查我的文件讀取 – spe 2012-03-06 16:46:10

+0

我已編輯文件,固定閱讀,但錯誤仍然存​​在 – spe 2012-03-07 08:15:55

0

您的閱讀文件的方式在開始時不正確。

不只是一次讀一個字符不是一個好主意,但循環是錯誤的。您可以使用istreambuf_iterator<char>輸入或read()以及gcount()確定何時讀取完成。