2012-03-06 18 views
2

を送るASIOファイルには、HTTP経由での.pngファイルを応答サーバーがあります:ブースト::

#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実装がいくつかあります。 1つの方法は、アプリケーションのサンプルコードの一部を再利用することです。

この特定のケースでは、どのように正確にオープンの例がありますと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

+0

私はこれを引き起こす可能性は全く考えていませんでしたが、回答を開始する前にリクエストを待たずに何かをする必要があります HTTPプロトコルの回線解析を少なくとも_ それ以外は、間違った行終了(HTTPは\ r \ nが期待されます)を除いて、間違っていることは間違いありませんが、私はそれがあなたの原因ではないかと疑います。 – Rawler

+0

あなたは大丈夫でした!おそらく、少なくともHTTPプロトコルのライン解析を行い、ダブル改行文字を受け取るまで待つべきでしょう。 – spe

1

最初にHTTP要求を受信して​​デコードし、要求された内容の場合にのみコンテンツを送信する必要があります。ブラウザは他のリソースも要求することがあります。予期せぬことを送信したり、リクエストを送信する前に送信したりすると、彼らは気分が悪くなる可能性があります。

また、データサイズにはオフバイアールエラーがあります。data.size()-1をヘッダーに入れて、dataのすべてを送信します。おそらくこれはreadMapのバグの部分的な回避策で、EOFに達した後に余分な文字をプッシュします。あなたは読むことの後で文字を押す前にeof()をチェックすることでそれを解決する方が良いでしょう。またはのような、より少ないエラーが発生しやすい(と、より効率的な)方法で読み込むことにより:また

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

、私はstringベクターをコピーする理由は表示されません。 vectorasio::bufferにも変換できます。

+0

私はそうは考えていません。私はちょうどカール(それはサーバーに予期しない何も送信しない)とそれをダウンロードしようとしました 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 カール:( 5636)Recv failure:ピアで接続がリセットされました – spe

+0

ファイルを確認します – spe

+0

ファイルを修正しましたが、エラーはまだあります。 – spe

0

ファイルの読み方が間違っています。

単純に1文字ずつ読むのは良い考えではありませんが、ループが間違っています。 を入力するか、read()を文字数で入力して、gcount()で読み取りが完了した時点を判断できます。