boost :: asio文件发送

时间:2012-03-06 16:28:01

标签: c++ boost-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 个答案:

答案 0 :(得分: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最终使其异步?)

答案 1 :(得分: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

答案 2 :(得分:0)

您开始阅读文件的方式不正确。

不仅仅是一次读取一个字符并不是一个好主意,但循环是错误的。您可以使用istreambuf_iterator<char>输入或read()使用多个字符gcount()来确定阅读何时完成。