Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.21.248.119] |
|
Страницы: (2) [1] 2 все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
Здравствуйте. Решил написать самый простой http сервер на asio.
#include <boost/asio.hpp> #include <thread> using boost::asio::ip::tcp; const char data[]="HTTP/1.0 200 OK\r\n" "Content-Length: 67\r\n" "Content-Type: text/html\r\n" "\r\n" "<html><body>The quick brown fox jumps over the lazy dog<br/><body/>"; void session(tcp::socket sock) { sock.send(boost::asio::buffer(data, sizeof(data)); } int main(int argc, char *argv[]) { boost::asio::io_service io_service; tcp::acceptor a(io_service, tcp::endpoint(tcp::v4(), 80)); for (;;) { tcp::socket sock(io_service); a.accept(sock); std::thread(session, std::move(sock)).detach(); } return 0; } Запускаю браузер. И страничка то отображается, то нет. В чем проблема -не могу понять. Когда у клинта происходит ошибка,то пишет, Sockert Error 1024. Connection reset by peer. Помогите пожалуйста разобраться. |
Сообщ.
#2
,
|
|
|
сокет разрушается быстрее, чем успевает выполниться send
|
Сообщ.
#3
,
|
|
|
Кстати да, дропать сокет сразу после отсылки - не самая лучшая идея. Исходя хотя бы из того, что некоторые HTTP-соединения будут keep-alive (всё ж версия HTTP 1.1 уже давно стала стандартом де-факто, поэтому вполне возможен вариант, что никто не проверяет Ваш HTTP/1.0).
http://www.lib.ru/WEBMASTER/rfc2068/section-8.html |
Сообщ.
#4
,
|
|
|
Клиент и сервер - на одной машине?
Цитата UncleBob @ сокет разрушается быстрее, чем успевает выполниться send Такое возможно, и в API это решается с помощью SO_LINGER. Правда данные слишком маленькие. Поэтому может дело в алгоритме Nagle? |
Сообщ.
#5
,
|
|
|
Цитата Oleg2004 @ Такое возможно, и в API это решается с помощью SO_LINGER. Да там же объект сокета убивается сразу после запуска потока... Если поток успел отработать, то есть шанс, что данные послались, а если продолжилось выполнение главного - пока-пока... |
Сообщ.
#6
,
|
|
|
Цитата UncleBob @ Да там же объект сокета убивается сразу после запуска потока. Я не особенный поклонник буста, потому в коде почему то этого не вижу Ткните, где это - буду очень признателен. Век живи, век учись |
Сообщ.
#7
,
|
|
|
Цитата iSherhan @ tcp::socket sock(io_service); здесь создается с++ объект sock типа tcp::socket он будет удален при выходе за область видимости, то есть при завершении шага цикла. далее, я не уверен, что именно делает std::move, это какая-то новая фишка с++, которым я уже не занимаюсь много лет, но по тому что я вычитал, не похоже, чтобы она каким-то образом могла помешать удалению объекта sock, а как я подозреваю, удаление объекта влечет закрытие содержащегося в нем сокета. |
Сообщ.
#8
,
|
|
|
Мне кажется что если бы было в точности так, то у автора не было бы возможности вообще что получить хоть раз.
Цитата iSherhan @ Запускаю браузер. И страничка то отображается, то нет. Кроме того, при возврате к началу бесконечного цикла он снова создает сокет - правда уже другой Впрочем, автор замолчал... |
Сообщ.
#9
,
|
|
|
Цитата Oleg2004 @ Мне кажется что если бы было в точности так, то у автора не было бы возможности вообще что получить хоть раз. Как раз описанное автором подтверждает мое предположение, потому как все зависит от того, успеет ли сработать поток до завершения цикла (что вполне возможно), или нет. И если успевает - то все ок, а если нет, то сокет закрывается до send. А дальше - как шедулеру заблагорассудится. |
Сообщ.
#10
,
|
|
|
Кажется я начинаю что-то понимать.
Вы хотите сказать, что вызов std::thread(session, std::move(sock)).detach(); приводит к созданию асинхронного по отношению к основному процессу потока... Ну вот, если это так, то ваше предположение вполне... |
Сообщ.
#11
,
|
|
|
Цитата Oleg2004 @ Вы хотите сказать |
Сообщ.
#12
,
|
|
|
Цитата UncleBob @ далее, я не уверен, что именно делает std::move, это какая-то новая фишка с++, которым я уже не занимаюсь много лет, но по тому что я вычитал, не похоже, чтобы она каким-то образом могла помешать удалению объекта sock Но как раз это и происходит Это перемещение. Т.е. созданный в цикле сокет оказывается в функции void session(tcp::socket sock) В данном вопросе всё валидно. Добавлено Ну, а проблема, очевидно, в этом Цитата Remarks The send operation may not transmit all of the data to the peer. Consider using the write function if you need to ensure that all data is written before the blocking operation completes. |
Сообщ.
#13
,
|
|
|
Цитата MyNameIsIgor @ Ну, а проблема, очевидно, в этом Наврядли. Функция send()ничего не шлет в сеть, она лишь копирует из своего буфера в передающий буфер сокета модуля TCP. Приемный буфер сокета в модуле TCP по умолчанию достаточно велик в разных ОС - В Беркли-реализациях по умолчанию используются буфера отправки и приема размером в 4096 байт, более современные системы используют буфера размером от 8192 до 61 440 байт. А потому send() не сможет отправить свой буфер только тогда, когда буфер отправки сокета не может вместить данные из буфера приложения. В данном случае send() отправляет настолько мало данных, что этот вопрос даже и не встает. И они уходят совершенно спокойно без блокировки.. |
Сообщ.
#14
,
|
|
|
Цитата Oleg2004 @ Наврядли. Зачем предполагать, если ТС может легко проверить? |
Сообщ.
#15
,
|
|
|
Цитата MyNameIsIgor @ Зачем предполагать, если ТС может легко проверить? А шо такое TC? Total Commander? И если легко, то почему топикстартер не смог? А насчет предположений... Видите ли - все, что имеет коммерческое происхождение - как правило 100% работает. А вот любительский код - он таким и остается. Теоретические и практические консидерации по поводу send() известны уже лет 20 не менее.. и абсолютно детерминированы. А топикстартеру я бы порекомендовал сюда Насчет ТС...круто А бы не догадался никогда... |