LINUX.ORG.RU

boost::asio пропадают пакеты

 


0

3

Добрый день!

Есть сервер, написанный с помощью boost::asio, на него приходит пакеты не больше 200 байт, около 60 в минуту от 30 клиентов (gprs модемы)

После 5 минут с момента запуска часть пакетов не доходит до процесса и вообще до сервера тоесть tcpdump показывает только часть всех ожидающихся пакетов, если перезапускаю процесс то все пакеты и соединение получаю в течении первых 5 минут

strace висит на epoll_wait после первых 5 минут и иногда проходят пакеты от 1-2 клиентов

Помогите незнаю что делать и как дебажить уже. Код сервера: http://pastebin.com/qitai15m Спасибо!

Возможные причины:

memcpy(d, &data_, bytes_transferred) 

копирует неполные данные всегда в начало пакета. то есть, если пришло сначала только первые 3 байта, а затем вся остальная посылка, то в буфере d будут данные без первых трех байт.

Вообше, для реализации проверки приема полного пакета лучше использовать async_read_until.

anymouse ()

tcpdump работает с сетевухой в promiscuous режиме (xто на интерфейс физически попало, то он и показывает). Если tcpdump не показывает часть пакетов, то они просто не дошли.

mv ★★★★★ ()
Ответ на: комментарий от mv

Спасибо! У меня есть такой же сервер на чистом epoll на нем все доходит, но тоже есть такие проблемы, но они появляются раз в неделю. Вроде все сделал как в примерах...

Dronnikkl ()
Ответ на: комментарий от vasily_pupkin

У меня есть такой же сервер на epoll и на нем по истечении трех дней примерно происходит следущее, приходят пакеты от 2 - 3 клиентов хотя должно приходить от 30 - я уверен в этом! после ребута процесса все нормально, а ингода приходится ждать пока закроются все коннекты и только после закрития все соединение работа восстановливается, (причем я юзаю REUSE_ADDR, несмотря на это)

Главный то есть слушающий сокет работает так: ev.events = EPOLLIN | EPOLLET; и если на нем события то делаю accept до тех пор пока не вернятся EAGAIN

Коннекты так: ev.events = EPOLLIN | EPOLLET;

и делаю recv до EAGAIN

Считывать до EAGAIN - это как я понял обязательное условие, правильно?

Может моя проблема в том что на либой пакет от коннекта я должен отослать ответ и я делаю просто send(4 байта ) после recv? Может быть нужно сделать EPOLL_CTL_MOD c EPOLLIN | EPOLLET на EPOLLOUT | EPOLLET, на клиентских сокетах?

Dronnikkl ()
Ответ на: комментарий от Dronnikkl

Что я могу предоставить когда произойдет такая проблема, strace висит на epoll_wait в netstat порядка 12 коннектов - как и при нормальной работе , сопаставлял время tcpdump прихода пакета и возврат из epoll_wait - все совпадает, есть аналогичный сервер только для двух клиентов на другом порту там все отлично в тот момент когда не доходят пакеты

Dronnikkl ()
Ответ на: комментарий от vasily_pupkin

когда я открываю новое соединение с сервером и шли пакеты с помощью самописного клиента то пакеты от моего клиента проходят нормально, следовательно с новым коннектом все отрабатывается и доставляется правильно, а с уже существующими или бывшими немного ранее все плохо

Dronnikkl ()
Ответ на: комментарий от Dronnikkl

Или может быть, хоть в смане написано что достачно close сделать для закрытия, все таки стоит делать EPOLL_CTL_DEL , потому что у меня сейчас просто close для закрытия

Dronnikkl ()

А буст копирует твой буфер который ты на стеке задал?

boost::asio::async_write(socket_, boost::asio::buffer(packetAnswer, 4), boost::bind(&session::handle_write, this, boost::asio::placeholders::error))

не охото смотреть, но думаю в нормальной сетевой либе boost::asio::buffer - обертка над указателем и его длинной. Когда ты стартуешь операцию, тк движек асинхронный, то она ставится в очередь и ты выходишь из handle_read удаляя стековую переменную packetAnswer. на следующей операции io_service идет чтение в несуществующий буфер на 4 байта.

Как вариант, не охото смотреть буст :D

meil ()
Ответ на: комментарий от meil

Так же строка 31 Packet pack; Не видно контекста использования : Server->onConnect(&pack, &socketMy); и int dataCount = Server->onData(&pack, &socketMy);

meil ()
Ответ на: комментарий от meil

Спасибо! сделал PacketAnswer членом класса, но все равно тоже самое

Dronnikkl ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.