GMainLoop和TCP侦听线程阻塞

时间:2014-01-09 16:33:50

标签: c++ multithreading sockets tcp glib

我需要你的帮助。

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

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

然后听socket:

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

所有正常和超时功能正常工作,直到任何未连接到已侦听套接字的客户端。连接后,客户端连接的所有时间超时都不起作用。我认为它与线程相关联,就像GLib文档中的默认GMainContext一样,所有操作都在一个线程中执行。我用这个修改了代码:

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

但现在已经监听了套接字,但没有任何客户端可以连接到它,并且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);

仅当连接关闭或错误通过TCP交换数据时,DoCycle()才返回'-1'。

有什么问题? 谢谢!

1 个答案:

答案 0 :(得分:1)

问题在于功能int ControlServer::GThStart(),您应该将GSource添加到GMainContext的{​​{1}},而不是新的上下文,请尝试使用:

GMainLoop