【问题标题】:GMainLoop and TCP Listen thread blockingGMainLoop 和 TCP Listen 线程阻塞
【发布时间】:2014-01-09 16:33:49
【问题描述】:

我需要你的帮助。

我有带有附加超时回调的主循环 GMainLoop:

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

并监听套接字:

int ControlServer::GStart()
 {
   int listenfd;
   GIOChannel *in;
   socklen_t addr_len;
   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);
   g_io_channel_unref(in);
   return 0;
 }

All's good 和 timeout 功能正常工作,直到任何客户端未连接到侦听的套接字。连接后,客户端连接时超时不工作。我认为它与线程连接,因为默认 GMainContext 中的 GLib 文档中的所有操作都在一个线程中执行。我用这个修改了代码:

int ControlServer::GThStart()
 {
  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);
  g_source_set_callback(Source, (GSourceFunc) Handler, (gpointer) Rec, NULL);
  Context = g_main_context_new();
  g_source_attach(Source, Context);
  g_source_unref(Source);
  return 0;
}

但是现在socket被监听了,但是没有任何客户端可以连接到它,并且从未调用过Handler函数。

处理程序代码如下:

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;
}

“访问”类检查客户端的权限并在客户端或服务器未关闭连接时通过实现无限循环执行协议交换。

  do
    {
      result = DoCycle(Rec);
      sprintf(str, "DEBUG: DoCycle(Rec) returns '%d'\n", result);
      AppendLog(str, class_name, DEBUG);
    } while (result != -1);

DoCycle() 仅在连接关闭或通过 TCP 交换数据出错时返回“-1”。

怎么了? 谢谢!

【问题讨论】:

  • 处理程序是什么样的?
  • 我刚刚添加了Handler的代码和一些解释。

标签: c++ multithreading sockets tcp glib


【解决方案1】:

问题在于函数int ControlServer::GThStart(),您应该将GSource 添加到您的GMainContextGMainLoop,而不是新的上下文中,试试吧:

g_source_attach(Source,g_main_loop_get_context(MainLoop));

【讨论】:

    猜你喜欢
    • 2014-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-14
    • 2010-11-22
    • 2019-10-30
    • 2021-04-17
    • 2012-06-13
    相关资源
    最近更新 更多