Модераторы: feodorv

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> баг asio? или баг TCP стека? 
V
    Опции темы
boostcoder
Дата 10.4.2011, 13:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 13
Всего: 110



Цитата(MAKCim @  10.4.2011,  13:33 Найти цитируемый пост)
еще раз убедился в том, как С++ на примере boost'а усложняет жизнь
было бы что-то другое, можно было посмотреть реализацию и выяснить все вопросы
лезть же в boost удовольствие сомнительное ;)

но не писать же свою реализацию сокетов со всем вытекающим...

я еще неделю назад подумывал использовать POCO. но это не удобно, тянуть в проект еще что-то. у меня проект полностью написан с использованием буста. ну еще openssl...


Это сообщение отредактировал(а) boostcoder - 10.4.2011, 13:45
PM WWW   Вверх
mes
Дата 10.4.2011, 13:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 1
Всего: 250



Цитата(boostcoder @  10.4.2011,  12:36 Найти цитируемый пост)
значит нужно автора asio закидать письмами с четкими вопросами.

пока вопросы возникшие в этой теме освещены документацией... не смотря на то, что она действительно скудная.. 
;)

Добавлено через 41 секунду
Цитата(boostcoder @  10.4.2011,  12:39 Найти цитируемый пост)
но не писать же свою реализацию сокетов со всем вытекающим...

asio Вас уже испугало ?  smile  smile

Добавлено через 5 минут и 47 секунд
Цитата(boostcoder @  10.4.2011,  12:36 Найти цитируемый пост)
что конкретно нужно изменить?

при чтении не делать start_write,
a добавлять в очередь, из которой забирать по writen..

Добавлено через 8 минут и 47 секунд
Цитата(MAKCim @  10.4.2011,  12:33 Найти цитируемый пост)
еще раз убедился в том, как С++ на примере boost'а усложняет жизнь

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


--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 10.4.2011, 13:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 13
Всего: 110



Цитата(mes @  10.4.2011,  12:19 Найти цитируемый пост)
и еще сервер получив неправильный блок, переправлял его как полный клиенту.. поэтому ошибка только в логах server_out и client_in..

это не так.
в последней версии исходников, я сделал проверку на сервере, на предмет порченных/неожидаемых данных. сервер ни разу не обнаружил несоответствие во входящих данных.

Добавлено через 1 минуту и 50 секунд
Цитата(mes @  10.4.2011,  13:39 Найти цитируемый пост)
при чтении не делать start_write,
a добавлять в очередь, из которой забирать по writen..

переделаю. не вопрос.
PM WWW   Вверх
mes
Дата 10.4.2011, 13:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 1
Всего: 250



Цитата(boostcoder @  10.4.2011,  12:49 Найти цитируемый пост)
сервер ни разу не обнаружил несоответствие во входящих данных.

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

Цитата(boostcoder @  10.4.2011,  12:49 Найти цитируемый пост)
переделаю. не вопрос. 

и должен стать порядок и на сервере smile




--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 10.4.2011, 14:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 13
Всего: 110



Цитата(MAKCim @  10.4.2011,  13:30 Найти цитируемый пост)
правда насчет атомарности записи данных (данные каждого sendmsg() запишутся непрерывно) не уверен

хм.. а это очень любопытно..

Добавлено @ 14:15
Цитата(mes @  10.4.2011,  13:39 Найти цитируемый пост)
добавлять в очередь, из которой забирать по writen..

а если очередь пуста, то по какому событию делать проверку/перезапуск отправки из очереди?

Добавлено @ 14:16

ужо 2.2 мильярда)

total requests  : 2212348580
total answers   : 2212269496


Добавлено @ 14:17
Цитата(mes @  10.4.2011,  13:39 Найти цитируемый пост)
при чтении не делать start_write,
a добавлять в очередь, из которой забирать по writen..

хотя.. не вижу принципиальной разницы.. в чем она?

Добавлено @ 14:22
Цитата(MAKCim @  10.4.2011,  13:30 Найти цитируемый пост)
правда насчет атомарности записи данных (данные каждого sendmsg() запишутся непрерывно) не уверен

а разве sendmsg() и recvmsg() не используют writev() и readv() ?
хотя ни в одной из моих книжек по программированию для линукс, не говорится об атомарности записи/чтения... погуглю..

Это сообщение отредактировал(а) boostcoder - 10.4.2011, 14:31
PM WWW   Вверх
mes
Дата 10.4.2011, 15:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 1
Всего: 250



Цитата(boostcoder @  10.4.2011,  13:13 Найти цитируемый пост)
хотя.. не вижу принципиальной разницы.. в чем она?

представьте ситуацию когда на два чтения должна происходить одна запись smile

Добавлено через 1 минуту и 46 секунд
Цитата(boostcoder @  10.4.2011,  13:13 Найти цитируемый пост)
а если очередь пуста, то по какому событию делать проверку/перезапуск отправки из очереди?

добавить флаг.. если очередь пуста и нет активной write, то после добавления стартовать ее, иначе просто добавлять.. 



--------------------
PM MAIL WWW   Вверх
phprus
Дата 10.4.2011, 17:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 129
Регистрация: 22.8.2006

Репутация: 1
Всего: 3



Цитата(boostcoder @  10.4.2011,  15:34 Найти цитируемый пост)
да.
завтра смогу проверить на 1гбит канале.

Напиши, пожалуйста, результаты (% использования канала) и RTT канала.
PM MAIL WWW ICQ   Вверх
boostcoder
Дата 10.4.2011, 18:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 13
Всего: 110



phprus, ок. отпишусь.

mes, вот что получилось. изменил только сервер. оно даже работает smile
Код


#include <iostream>
#include <queue>
#include <boost/bind.hpp>
#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <boost/lexical_cast.hpp>

#include "header.hpp"

/***************************************************************************/

struct queue {
   void push(char* ptr) {
      boost::mutex::scoped_lock locker(mutex);
      queue.push(ptr);
   }

   char* pop() {
      boost::mutex::scoped_lock locker(mutex);
      if ( queue.empty() ) return 0;
      char* ptr = queue.front();
      queue.pop();
      return ptr;
   }

   bool empty() const {
      boost::mutex::scoped_lock locker(mutex);
      return queue.empty();
   }

private:
   mutable boost::mutex mutex;
   std::queue<char*> queue;
} q;

bool in_process = false;

/***************************************************************************/

void start_write(boost::asio::ip::tcp::socket&);

void writen(boost::asio::ip::tcp::socket&,
            char*,
            const boost::system::error_code&,
            size_t);

void start_read(boost::asio::ip::tcp::socket&);

void readed(boost::asio::ip::tcp::socket&,
            char*,
            const boost::system::error_code&,
            size_t);

/***************************************************************************/

void start_write(boost::asio::ip::tcp::socket& sock) {
   if ( char* buf = q.pop() ) {
      boost::asio::async_write(
         sock,
         boost::asio::buffer(buf, send_buffer_size),
         boost::bind(
            &writen,
            boost::ref(sock),
            buf,
            boost::asio::placeholders::error,
            boost::asio::placeholders::bytes_transferred
         )
      );
   }
}

void writen(boost::asio::ip::tcp::socket& sock,
            char* buf,
            const boost::system::error_code& e,
            size_t wr)
{
   if ( e ) {
      throw std::runtime_error("writen(): " + e.message());
   }

   if ( wr != send_buffer_size ) {
      std::cout
      << "writen(): " << buf << ", len: " << wr << std::endl;
   }

   delete[] buf;

   if ( !q.empty() ) {
      in_process = true;
      start_write(sock);
   } else {
      in_process = false;
   }
}

/***************************************************************************/

void start_read(boost::asio::ip::tcp::socket& sock) {
   char* buf = new char[recv_buffer_size];
   boost::asio::async_read(
      sock,
      boost::asio::buffer(buf, recv_buffer_size),
      boost::bind(
         &readed,
         boost::ref(sock),
         buf,
         boost::asio::placeholders::error,
         boost::asio::placeholders::bytes_transferred
      )
   );
}

void readed(boost::asio::ip::tcp::socket& sock,
            char* buf,
            const boost::system::error_code& e,
            size_t rd)
{
   if ( e ) {
      throw std::runtime_error("read handler: " + e.message());
   }

   if ( rd != recv_buffer_size ) {
      std::cout
      << "readed(): " << buf << ", len: " << rd << std::endl;
   }

   static boost::uint64_t idx = 0;
   boost::uint64_t tmp = atoll(buf);
   if ( idx != tmp ) {
      fprintf(stdout, "expected: %12llu, get: %12llu, buf: %s", idx, tmp, buf);
      fflush(stdout);
   }

   ++idx;

   q.push(buf);

   if ( !in_process ) {
      in_process = true;
      start_write(sock);
   }
   
   start_read(sock);
}

/***************************************************************************/

int main(int argc, char** argv) {
   if ( argc != 3 ) {
      std::cout << "server ip port" << std::endl;
      return 0;
   }

   if ( init_wrappers() ) {
      return -1;
   }
   try {
      std::string ip = argv[1];
      boost::uint16_t port = atoi(argv[2]);
/*
      dbg::in = fopen("server_in.log", "wb");
      dbg::out= fopen("server_out.log", "wb");
      if ( !dbg::out || !dbg::in ) {
         std::cout << "can`t open file!" << std::endl;
         return 1;
      }
*/
      boost::asio::ip::tcp::endpoint endpoint(
         boost::asio::ip::address::from_string(ip), port
      );

      boost::asio::io_service ios;
      boost::asio::ip::tcp::acceptor acceptor(ios, endpoint);
      boost::asio::ip::tcp::socket socket(ios);

      acceptor.accept(socket);
      std::cout << "new connection from: " << socket.remote_endpoint().address().to_string() << std::endl;

      boost::asio::socket_base::non_blocking_io non_blocking_io(true);
      socket.io_control(non_blocking_io);

      start_read(socket);
      
      ios.run();
   } catch ( const std::exception& e ) {
      std::cout << "(exception): " << e.what() << std::endl;
   }
/*
   fclose(dbg::in);
   fclose(dbg::out);
*/
}

/***************************************************************************/



PM WWW   Вверх
boostcoder
Дата 10.4.2011, 18:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 13
Всего: 110



зы
нехочу постоянно помнить о познаных ограничениях. хочу обертку над сокетом. умную. удобную.

PM WWW   Вверх
mes
Дата 10.4.2011, 18:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 1
Всего: 250



Цитата(boostcoder @  10.4.2011,  17:02 Найти цитируемый пост)
вот что получилось. изменил только сервер.оно даже работает. smile

Цитата(mes @  10.4.2011,  12:56 Найти цитируемый пост)
значит тогда клиент в порядке.. получается, что рубились только на сервере.. 

smile
Цитата(boostcoder @  10.4.2011,  17:20 Найти цитируемый пост)
нехочу постоянно помнить о познаных ограничениях. хочу обертку над сокетом. умную. удобную. 

а разве asiо не предлагает ? ту которую Вы раньше применяли, в той длинной теме..

Добавлено @ 18:58
оглянувшись назад, можно оценить насколько пророчески были слова MAKCim
Цитата(MAKCim @  29.3.2011,  13:28 Найти цитируемый пост)
Цитата(boostcoder)

насколько это возможно утверждать на приведенном коде - да. просто код реально мегапрост, чтоб где-то мог закрасться баг. если конечно это не баг asio. в чем сомневаюсь.. 


в этом большая ошибка
я много раз на это же полагался
а в итоге как раз в мегапростом коде и был баг ;)

 smile  smile 


Это сообщение отредактировал(а) mes - 10.4.2011, 18:58


--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 10.4.2011, 18:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 13
Всего: 110



Цитата(mes @  10.4.2011,  18:55 Найти цитируемый пост)
а разве asiо не предлагает ? ту которую Вы раньше применяли

что-то не помню.
ладно, тему можно закрывать. а по поводу обертки создам новую тему. в общем разделе smile

Добавлено через 52 секунды
Цитата(mes @  10.4.2011,  18:55 Найти цитируемый пост)
оглянувшись назад, можно оценить насколько пророчески были слова MAKCim

это да.
не в первый раз раз себя на таком ловлю... эх..
PM WWW   Вверх
MAKCim
Дата 10.4.2011, 19:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 6
Всего: 207



Цитата(boostcoder @  10.4.2011,  14:13 Найти цитируемый пост)
а разве sendmsg() и recvmsg() не используют writev() и readv() ?

нет

Добавлено через 4 минуты и 45 секунд
boostcoder
сейчас, кстати посмотрел код ядра и немного офигел
http://tomoyo.sourceforge.jp/cgi-bin/lxr/s...ipv4/tcp.c#L914
что-то я не вижу локов
это наводит на мысль, что в linux'е лучше не пытаться писать в сокет из более одного потока без своих локов

Добавлено через 7 минут и 56 секунд
 smile 
Цитата(boostcoder @  10.4.2011,  18:59 Найти цитируемый пост)
не в первый раз раз себя на таком ловлю... эх.. 

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

просто когда много раз об это спотыкаешься, начинаешь относится к себе более критически дабы решить проблему быстрее


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
boostcoder
Дата 10.4.2011, 19:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 13
Всего: 110



Цитата(MAKCim @  10.4.2011,  19:04 Найти цитируемый пост)
психика у нас устроена таким образом, что мы априори не хотим признавать, что ошибка может быть у нас

это правда smile 
PM WWW   Вверх
MAKCim
Дата 10.4.2011, 19:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 6
Всего: 207



короче я нагнал
лок там есть в самом верху, я проглядел, паника отменяется smile 


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
boostcoder
Дата 10.4.2011, 19:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 13
Всего: 110



Цитата(MAKCim @  10.4.2011,  19:04 Найти цитируемый пост)
нет

в структуре msghdr есть такой член:
Код

struct msghdr {
    ...
    struct iovec *msg_iov; <<<<<<<<<<<<<<
    ...
};


эта же структура используется и для writev(). вот я и подумал, что в sendmsg() используется writev() дабы не плодить код.

Цитата(MAKCim @  10.4.2011,  19:04 Найти цитируемый пост)
сейчас, кстати посмотрел код ядра и немного офигел
http://tomoyo.sourceforge.jp/cgi-bin/lxr/s...ipv4/tcp.c#L914
что-то я не вижу локов
это наводит на мысль, что в linux'е лучше не пытаться писать в сокет из более одного потока без своих локов

ну вот, еще полезная информация.

Добавлено через 52 секунды
Цитата(MAKCim @  10.4.2011,  19:24 Найти цитируемый пост)
лок там есть в самом верху

это он? :
Цитата

lock_sock(sk);

PM WWW   Вверх
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Сети | Следующая тема »


 




[ Время генерации скрипта: 0.1113 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.