Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Работа с libevent
|
|||
|---|---|---|---|
|
#18+
Здравствуйте! Используя метод bufferevent_read библиотеки libevent, столкнулся с проблемой принятия файла большого размера. При использовании обычных сокетов делал это в цикле, с помощью метода recv, при этом перед запуском цикла принимал размер файла, и для остановки цикла сравнивал этот размер с общим числом принятых байт, по частям записывая файл. Так как при реализации сервера через libevent чтение сообщения - это событие, получается что реализовать подобным способом здесь не получится - каждый новый прием данных заставляет метод приема выполнятся заново, и получается, что переданный файл записывается по частям в разные буферы, т.е. в один, но в конце приема в буфере остается только последние принятые байты файла. Вопрос как реализовать прием файлов больших размеров используя libevent. Спасибо! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.01.2014, 10:28 |
|
||
|
Работа с libevent
|
|||
|---|---|---|---|
|
#18+
La France, могу сказать только одно:очень странно, что именно ты пишешь этот самый высоко загруженный сервер, а не я. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.01.2014, 12:08 |
|
||
|
Работа с libevent
|
|||
|---|---|---|---|
|
#18+
MasterZiv, Почему странно? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.01.2014, 12:15 |
|
||
|
Работа с libevent
|
|||
|---|---|---|---|
|
#18+
La Franceкаждый новый прием данных заставляет метод приема выполнятся заново, и получается, что переданный файл записывается по частям в разные буферы, т.е. в один, но в конце приема в буфере остается только последние принятые байты файла. А писать в разные буферы, т.е. действительно в разные тебе мешает что?.. Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.01.2014, 14:01 |
|
||
|
Работа с libevent
|
|||
|---|---|---|---|
|
#18+
Dimitry SibiryakovLa Franceкаждый новый прием данных заставляет метод приема выполнятся заново, и получается, что переданный файл записывается по частям в разные буферы, т.е. в один, но в конце приема в буфере остается только последние принятые байты файла. А писать в разные буферы, т.е. действительно в разные тебе мешает что?.. Как я потом соберу все в один буфер, так чтобы эти составные буферы не перепутались? Но как вариант попробую, с этим что-нибудь придумать. Спасибо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.01.2014, 14:13 |
|
||
|
Работа с libevent
|
|||
|---|---|---|---|
|
#18+
La FranceКак я потом соберу все в один буфер, так чтобы эти составные буферы не перепутались? Последовательно. Ты не поверишь, но порядок приёма не нарушается. Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.01.2014, 14:30 |
|
||
|
Работа с libevent
|
|||
|---|---|---|---|
|
#18+
Не понял, откуда несколько буферов? На каждое соединение - один буфер. В этот буфер читаем из потока. Когда приходит событие чтения, записываем буфер в файл, и потом снова запускаем чтение в тот же буфер, пока не будет прочитано все что ожидается. Потом через этот же буфер отправляем ответ в сокет. Где у вас возникают несколько буферов? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.01.2014, 14:48 |
|
||
|
Работа с libevent
|
|||
|---|---|---|---|
|
#18+
Anatoly MoskovskyВ этот буфер читаем из потока. тут имел в виду "читаем из сокета" ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.01.2014, 14:50 |
|
||
|
Работа с libevent
|
|||
|---|---|---|---|
|
#18+
Dimitry SibiryakovПоследовательно. Ты не поверишь, но порядок приёма не нарушается. Это понятно. А как быть с тем, что локальный буфер, который в методе чтения будет перезаписываться, каждый раз как возникнет новое событие чтения, а значит старые данные из этого буфера потеряются. Использовать в этом случае глобальную переменную для буфера, в который будет суммироваться все прочитанные байты нельзя, ведь у меня не один клиент и её(глобальную переменную) будут использовать все, следовательно в ней всегда будет черт знает что храниться. Это можно было бы решить написав структуру для новых подключений, где и хранился бы конечный буфер. Но все это, как мне кажется, неправильно, ведь все должно прочитаться за одно выполнение метода чтения, а не быть разбросано по разным событиям. Сейчас у меня вроде все байты читаются и ничего не теряется. Теперь нужно сделать так, чтобы это событие как-то блокировалось на время выполнения метода чтения, а по его завершению снова активировалось. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.01.2014, 14:55 |
|
||
|
Работа с libevent
|
|||
|---|---|---|---|
|
#18+
La FranceА как быть с тем, что локальный буфер, который в методе чтения будет перезаписываться, каждый раз как возникнет новое событие чтения, а значит старые данные из этого буфера потеряются. Обработать эти старые данные перед возвратом из обработчика. На худой конец - скопировать в более другой буфер. Разве это не очевидно?.. Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.01.2014, 15:01 |
|
||
|
Работа с libevent
|
|||
|---|---|---|---|
|
#18+
Anatoly MoskovskyНе понял, откуда несколько буферов? На каждое соединение - один буфер. Все правильно. На каждое соединение буфер один. Anatoly MoskovskyВ этот буфер читаем из сокета. Когда приходит событие чтения, записываем буфер в файл, и потом снова запускаем чтение в тот же буфер, пока не будет прочитано все что ожидается. Потом через этот же буфер отправляем ответ в сокет. Таким образом я реализовывал сервер на стандартных сокетах с использованием потоков, и у меня все замечательно работало. Но с использование libevent данные читаются/отсылаются не из/в сокет(-а), а из/в объект(-а) структуры bufferevent с помощью подобного recv методу bufferevent_read, который тоже возвращает число считанных байт. По сути, с использованием libevent не имеет значения откуда считывать данные - из сокета(есть возможность совместить стандартные сокеты и libevent для реализации сервера, но сказали делать только с помощью libevent) или объекта структуры bufferevent, так как в любом случае будет срабатывать событие чтения пока из сокета или объекта структуры bufferevent есть что читать. И получается, что не успеет метод полностью прочитать все присланные байты файла, как срабатывает событие чтения и часть данных считывается в другом вызове метода, в ТОТ же буфер, но так как он является локальным для метода, то он же является и другим по отношению к другому вызову метода. Надеюсь в последнем предложении я ответил на ваш вопрос относительно того где возникают несколько буферов. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.01.2014, 15:26 |
|
||
|
Работа с libevent
|
|||
|---|---|---|---|
|
#18+
La France, Не, про буфера так и не понял. Ну да ладно. Это не принципиально. Но суть в том, что не может прийти следующее событие, пока находимся внутри обработчика. Таким образом, чтобы все работало вам надо к моменту выхода из обработчика чтения закончить обработку данных в буфере. А пока вы не выйдете из обработчика никто ваш буфер не тронет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.01.2014, 15:34 |
|
||
|
Работа с libevent
|
|||
|---|---|---|---|
|
#18+
Dimitry SibiryakovОбработать эти старые данные перед возвратом из обработчика. На худой конец - скопировать в более другой буфер. Разве это не очевидно?.. Это очевидно. Свои мысли по этому поводу я высказал в том же сообщении. La FranceИспользовать в этом случае глобальную переменную для буфера, в который будет суммироваться все прочитанные байты нельзя, ведь у меня не один клиент и её(глобальную переменную) будут использовать все, следовательно в ней всегда будет черт знает что храниться. Это можно было бы решить написав структуру для новых подключений, где и хранился бы конечный буфер. Но все это, как мне кажется, неправильно, ведь все должно прочитаться за одно выполнение метода чтения, а не быть разбросано по разным событиям. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.01.2014, 15:37 |
|
||
|
Работа с libevent
|
|||
|---|---|---|---|
|
#18+
La FranceDimitry SibiryakovОбработать эти старые данные перед возвратом из обработчика. На худой конец - скопировать в более другой буфер. Разве это не очевидно?.. Это очевидно. Свои мысли по этому поводу я высказал в том же сообщении. La FranceИспользовать в этом случае глобальную переменную для буфера, в который будет суммироваться все прочитанные байты нельзя, ведь у меня не один клиент и её(глобальную переменную) будут использовать все, следовательно в ней всегда будет черт знает что храниться. Это можно было бы решить написав структуру для новых подключений, где и хранился бы конечный буфер. Но все это, как мне кажется, неправильно, ведь все должно прочитаться за одно выполнение метода чтения, а не быть разбросано по разным событиям. MasterZiv, Почему странно? Вот ПО ЭТОМУ и странно... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.01.2014, 15:51 |
|
||
|
Работа с libevent
|
|||
|---|---|---|---|
|
#18+
Anatoly MoskovskyНо суть в том, что не может прийти следующее событие, пока находимся внутри обработчика. Таким образом, чтобы все работало вам надо к моменту выхода из обработчика чтения закончить обработку данных в буфере. А пока вы не выйдете из обработчика никто ваш буфер не тронет. Не совсем согласен. Без конца щелкая по кнопке на форме все события будут обработаны, естественно, если обработчик не будет блокировать форму. Допустим в обработчике будет запущен бесконечный цикл, тогда форма зависнет, но если по каждому нажатию на кнопку циклы будут запускаться в новых потоках, то все они будут выполняться не блокируя форму. Думаю в libevent события работают подобным образом, поэтому срабатыванию нового события не мешает незаконченность обработки предыдущего. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.01.2014, 15:57 |
|
||
|
Работа с libevent
|
|||
|---|---|---|---|
|
#18+
MasterZivВот ПО ЭТОМУ и странно... Подобное объяснение мне не понятно. С намёками и сарказмом у меня проблемы. Поэтому, могу лишь сделать предположение к чему вы клоните. В любом случае, что мешает вам заняться написанием такого сервера, какой вас устроит? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.01.2014, 16:06 |
|
||
|
Работа с libevent
|
|||
|---|---|---|---|
|
#18+
La FranceMasterZivВот ПО ЭТОМУ и странно... Подобное объяснение мне не понятно. С намёками и сарказмом у меня проблемы. Поэтому, могу лишь сделать предположение к чему вы клоните. В любом случае, что мешает вам заняться написанием такого сервера, какой вас устроит? Я всё понимаю. Всё правильно. Лучше и не знать... А мешает -- отсутсвие времени и денег. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.01.2014, 16:30 |
|
||
|
Работа с libevent
|
|||
|---|---|---|---|
|
#18+
La France, Ты бы ужо КОД опубликовал бы, мож быстрее и помогли б. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.01.2014, 16:31 |
|
||
|
Работа с libevent
|
|||
|---|---|---|---|
|
#18+
La FranceБез конца щелкая по кнопке на форме все события будут обработаны, естественно, если обработчик не будет блокировать форму. Допустим в обработчике будет запущен бесконечный цикл, тогда форма зависнет, но если по каждому нажатию на кнопку циклы будут запускаться в новых потоках, то все они будут выполняться не блокируя форму. Думаю в libevent события работают подобным образом, поэтому срабатыванию нового события не мешает незаконченность обработки предыдущего. Да не работает libevent подобным образом. Там внутри одного цикла событий ровно один поток, и пока выполняется обработчик ничего больше не может в принципе выполняться. Грубо говоря внутри происходит следующее: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. Как вы видите событие приходит не после чтения в буфер, а перед ним. Т.е. неважно какие там события пришли пока ваш обработчик выполнялся, libevent с буфером работает только полсе того как обработчик завершится. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.01.2014, 21:02 |
|
||
|
Работа с libevent
|
|||
|---|---|---|---|
|
#18+
MasterZivА мешает -- отсутсвие времени и денег. Написание этого сервера является частью моей работы, поэтому вопроса о времени и деньгах у меня не стоит. MasterZivТы бы ужо КОД опубликовал бы, мож быстрее и помогли б. Переделываю эхо-сервер для своих задач. В методе echo_read_cb первый вариант был следующий: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. С использованием сокетов и потоков - это рабочий вариант, но только не здесь. Так как разные части файла читаются в разных вызовах этого метода, то число байт никогда не будет равно размеру файла, и уже при втором вызове метода size будет равен 0, так как это число будет преобразовываться из части байт файла. Сейчас вариант такой: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. Тут считываются все байты файла, но за несколько событий. Сейчас нужно как-то блокировать событие чтения на время выполнения метода, чтобы все байты файла читались за одно выполнение метода, а потом снова разблокировать это событие. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.01.2014, 07:03 |
|
||
|
Работа с libevent
|
|||
|---|---|---|---|
|
#18+
Anatoly MoskovskyКак вы видите событие приходит не после чтения в буфер, а перед ним. Т.е. неважно какие там события пришли пока ваш обработчик выполнялся, libevent с буфером работает только полсе того как обработчик завершится. Тем не менее факт остается фактом: Вывод -------------------------------------Событие: 1 n: 1024 n: 1024 n: 872 allBytes: 2920 -------------------------------------Событие: 2 n: 1024 n: 1024 n: 1024 n: 1024 allBytes: 4096 -------------------------------------Событие: 3 n: 1024 n: 1024 n: 1024 n: 1024 allBytes: 4096 -------------------------------------Событие: 4 n: 1024 n: 1024 n: 1024 n: 1024 allBytes: 4096 -------------------------------------Событие: 5 n: 1024 n: 1024 n: 1024 n: 1024 allBytes: 4096 -------------------------------------Событие: 6 n: 1024 n: 1024 n: 1024 n: 1024 allBytes: 4096 -------------------------------------Событие: 7 n: 1024 n: 1024 n: 1024 n: 1024 allBytes: 4096 -------------------------------------Событие: 8 n: 1024 n: 1024 n: 1024 n: 1024 allBytes: 4096 -------------------------------------Событие: 9 n: 1024 n: 1024 n: 1024 n: 1024 allBytes: 4096 -------------------------------------Событие: 10 n: 1024 n: 1024 n: 1024 n: 1024 allBytes: 4096 -------------------------------------Событие: 11 n: 1024 n: 1024 n: 1024 n: 1024 allBytes: 4096 -------------------------------------Событие: 12 n: 1024 n: 1024 n: 1024 n: 1024 allBytes: 4096 -------------------------------------Событие: 13 n: 1024 n: 1024 n: 1024 n: 1024 allBytes: 4096 -------------------------------------Событие: 14 n: 1024 n: 1024 n: 1024 n: 1024 allBytes: 4096 -------------------------------------Событие: 15 n: 1024 n: 1024 n: 1024 n: 1024 allBytes: 4096 -------------------------------------Событие: 16 n: 1024 n: 1024 n: 1024 n: 1024 allBytes: 4096 -------------------------------------Событие: 17 n: 1024 n: 1024 n: 1024 n: 1024 allBytes: 4096 -------------------------------------Событие: 18 n: 1024 n: 1024 n: 1024 n: 1024 allBytes: 4096 -------------------------------------Событие: 19 n: 1024 n: 1024 n: 1024 n: 1024 allBytes: 4096 -------------------------------------Событие: 20 n: 1024 n: 1024 n: 1024 n: 1024 allBytes: 4096 -------------------------------------Событие: 21 n: 1024 n: 1024 n: 1024 n: 1024 allBytes: 4096 -------------------------------------Событие: 22 n: 152 allBytes: 152 Здесь сервер принимает файл размером 84992, если посчитать все принятые байты - сложить все allBytes то получится 84992, то есть весь файл пришел, но прочитался за 22 события. Как-то так. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.01.2014, 07:18 |
|
||
|
Работа с libevent
|
|||
|---|---|---|---|
|
#18+
Сейчас выяснилось, что в цикле где происходит чтение, через несколько операций чтения - вызова метода bufferevent_read(как видно из вывода выше в основном через пять операций чтения, на пятый уже ничего не читает), метод возвращает 0, а следовательно он прекращает работу цикла (дает возможность сработать событию снова), но потом срабатывает новое событие и чтение продолжается. Вопрос: почему так происходит? Anatoly Moskovsky, теперь с вами согласен. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.01.2014, 07:45 |
|
||
|
Работа с libevent
|
|||
|---|---|---|---|
|
#18+
La France Код: plaintext 1. откуда уверенность, что сервер отдаст все ожидаемые байты? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.01.2014, 12:40 |
|
||
|
Работа с libevent
|
|||
|---|---|---|---|
|
#18+
[/src][/quot] откуда уверенность, что сервер отдаст все ожидаемые байты? [/quot] Если вы о том, что в случае, когда не все данные придут от клиента, то цикл никогда не завершится, то отвечу, что в реализации с сокетами у меня это обрабатывается и работает нормально. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.01.2014, 13:03 |
|
||
|
Работа с libevent
|
|||
|---|---|---|---|
|
#18+
La FranceТут считываются все байты файла, но за несколько событий. Сейчас нужно как-то блокировать событие чтения на время выполнения метода, чтобы все байты файла читались за одно выполнение метода, а потом снова разблокировать это событие. У вас в корне неверное понимание как асинхронная обработка происходит. Вы не можете в обработчике собятия чтения в цикле читать пока не прочтете нужное кол. байтов. Вместо этого вы должны при нехватке данных запрашивать новое чтение и выходить из обработчика чтения. А чтобы при приходе новых данных обработчик продолжил с того же места, вы должны хранить состояние обработки в неком объекте и каким-то образом передавать его в каждый обработчик. Как в libevent поддерживать состояние сеанса я уже не помню, давно ничего не нем не делал. Поэтому порекомендовал Boost.Asio где из предыдущего обработчика в следующий можно передавать произвольный набор аргументов. Не говоря уже про то, что там вообще все на порядки проще чем в libevent (К примеру, сервер , чья сетевая часть была написана мной на libevent за месяц, я переписал на Boost.Asio за один день) Но раз вам начальство приказало libevent использовать, то ищите более сложные примеры чем Echo в котором состояние не требуется поддерживать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.01.2014, 17:08 |
|
||
|
|

start [/forum/topic.php?fid=57&msg=38529339&tid=2019752]: |
0ms |
get settings: |
10ms |
get forum list: |
12ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
64ms |
get topic data: |
10ms |
get forum data: |
3ms |
get page messages: |
55ms |
get tp. blocked users: |
1ms |
| others: | 12ms |
| total: | 175ms |

| 0 / 0 |
