2012-03-06 3 views
2

Существует сервер, который Ответные файл .png над HTTP:повышение :: 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-документах есть несколько более полных 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

+0

У меня нет абсолютно никакой идеи, что может вызвать это, но это _might_ имеет какое-то отношение к тому, чтобы не дожидаться запроса до начала ответа. Возможно, вы должны, по крайней мере, выполнить парсинг по протоколу 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. vector также можно преобразовать в asio::buffer.

+0

Я не думаю, что это причина. Я просто попытался загрузить его с помощью curl (он не посылает ничего неожиданного на сервер) spe $ curl http://craft.omg-team.org> img.png % Всего% полученных% Xferd Средняя скорость Время Время Время Текущий Dload Загрузить Total Spent Левая скорость 65 1238k 65 817k 0 0 233k 0 0:00:05 0:00:03 0:00:02 243k curl: (56) Ошибка Recv: сброс соединения с помощью peer (извините за форматирование) – spe

+0

Я проверю свой файл, читающий – spe

+0

Я редактировал файл, фиксированное чтение, но ошибка все еще существует – spe

0

Ваш способ чтения файла неверен для начала.

Не просто, что чтение одного символа за раз - отличная идея, но цикл неправильный. Вы можете использовать istreambuf_iterator<char> для ввода или read() с количеством символов с gcount(), определяющим, когда чтение будет завершено.

Смежные вопросы