Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [GLIB] Нужна помощь с GMainLoop! Проблема с блокированием потока 
:(
    Опции темы
Xuch
Дата 31.12.2013, 14:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Здравствуйте, друзья!
Очень нужна помощь с GLib.
Есть GMainLoop - там основной цикл программы,  к нему добавлен таймер, по которому осуществляются некоторые действия. Все работало прекрасно, пока я не добавил слушающий сокет - теперь как только подключается клиент, пока он не отключится - таймер не срабатывает. Понимаю, что нужно как-то другим потоком прикрутить к основной GMainLoop, но как непонятно, т.к. в официальной документации только краткий абзац и далее описание функций, которое не помогает понять как организовать процесс в целом.


Исходная часть:
Код

  MainLoop = g_main_loop_new(NULL, FALSE);
  g_timeout_add_seconds(Interval, TimeoutCallback, (gpointer) Rec);
  g_main_loop_run(MainLoop);


Слушающий сокет:
Код

  listenfd = TcpListen(host, port, &addr_len);
  in = g_io_channel_unix_new(listenfd);
  g_io_add_watch(in, G_IO_IN, (GIOFunc) Handler, (gpointer) Rec);


Помучив документацию по GLib я состряпал нечто такое:
Код

  int listenfd;
  socklen_t addr_len;
  GIOChannel *Channel;
  GSource *Source;
  GMainContext *Context;

  listenfd = TcpListen(host, port, &addr_len);
  Channel = g_io_channel_unix_new(listenfd);
  Source = g_io_create_watch(Channel, G_IO_IN);
  Context = g_main_context_new();
  g_source_attach(Source, Context);


Однако здесь я не понимаю, как подключить обработчик. И вообще в том ли направлении я двигаюсь?

Заранее большое спасибо за любую помощь!
PM MAIL   Вверх
Xuch
Дата 11.1.2014, 13:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



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

Код

    gpointer ControlServer::GThSocket(gpointer data)
     {
       int listenfd;
       socklen_t addr_len;
       GIOChannel *Channel;
       GSource *Source;
       GMainContext *Context;

      ControlServer *Srv = (ControlServer *) data;
      Context = g_main_context_new();
      listenfd = Srv->TcpListen(Srv->host, Srv->port, &addr_len);
      Channel = g_io_channel_unix_new(listenfd);
      Source = g_io_create_watch(Channel, G_IO_IN|G_IO_ERR);
      g_source_set_funcs(Source, &GThSourceFuncs);
      g_source_set_callback(Source, (GSourceFunc) Handler, (gpointer) Srv->Rec, NULL);
      g_source_attach(Source, Context);
      g_source_unref(Source);
      return NULL;
     }

Код


    int ControlServer::GThStart()
     {
      GError *error = NULL;
      GThread *thread;

      g_thread_init(NULL);
      thread = g_thread_create(GThSocket, this, TRUE, &error);
      g_thread_join(thread);
      return 0;
     }


На данный момент проблема в том, что клиент не может подключиться к серверу, хотя при запуске программы через netstat я вижу, что целевой порт слушается. Видимо проблема где-то начиная с g_io_create_watch(), так как если я ее меняю на g_io_add_watch(), то сервер начинает работать. Но в этом случае при подключении клиента у меня отваливается таймер на gmainloop, а когда клиент отключается функция-callback таймера выполняется столько раз, сколько таймер срабатывал за время подключения клиента.

Получается ни один вариант неработоспособен.
Буду рад любым идеям!
Спасибо

Добавлено через 5 минут и 16 секунд
Привожу также код обработчика:

Код

bool ControlServer::Handler(GIOChannel *in, GIOCondition condition, gpointer data)
{
  Recorder *Rec = (Recorder *) data;
  struct sockaddr_storage income;
  int insock, newsock;
  socklen_t income_len;
  struct sockaddr peer;
  socklen_t size;
  Access *access;

  insock = g_io_channel_unix_get_fd(in);
  income_len = sizeof(income);
  newsock = accept(insock, (struct sockaddr *) &income, &income_len);
  size = sizeof(peer);
  getpeername(newsock, &peer, &size);
  struct sockaddr_in *ipv4 = (struct sockaddr_in *) &peer;
  access = new Access(newsock, ipv4, MAXN);

  access->Cycle(Rec);

  delete access;
  return true;
}


Access - это класс, который получает сокет клиента, проверяет права доступа и осуществляет протокольный обмен с клиентом.
access->Cycle(Rec) - это бесконечный цикл до того времени, пока клиент или сервер не закроют соединение.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Кроссплатформенное программирование, QT/Gtk+/wxWidgets"
JackYF
Любитель
  • В заголовке темы в квадратных скобках обозначьте используемую вами библиотеку, например: [QT],[GTK],[wx].
  • Если вопрос актуален только для некоторой версии библиотеки, либо, если вы пользуетесь не самой последней версией, укажите это. Например: [QT4], [GTK2].
  • Все начинающие изучать Qt - не забудьте зайти сюда.
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • В вопросе укажите полную версию версию библиотеки, а также все дополнительные используемые программные пакеты.
  • Не забывайте пользоваться кнопкой "Код".
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к тематике этого раздела. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, Любитель.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets | Следующая тема »


 




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


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

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