c++ - 回调 g_source_set 回调总是被调用?

标签 c++ c glib

我正在学习 gsocket,并想尝试编写一个简单的程序来处理我收到的任何数据包,但是当只有一个数据包到来时,函数回调总是被调用。这是我的简单代码:

#include <glib.h>
#include <gio/gio.h>
#include <libsoup/soup.h>
#include <glib-object.h>

gboolean has_packet(GIOChannel *source, GIOCondition condition, gpointer data){
    g_printf("has packet\n");

    return TRUE;
}

int main(int argc, char **argv) {
    g_type_init();

    GInetAddress *iface_address = g_inet_address_new_from_string ("0.0.0.0");
    GSocketAddress *bind_address = g_inet_socket_address_new (iface_address, 12345);
    GSocket *sock;
    GError *err = NULL;
    sock = g_socket_new(G_SOCKET_FAMILY_IPV4,
                    G_SOCKET_TYPE_DATAGRAM,
                    G_SOCKET_PROTOCOL_UDP,
                    &err);
    g_assert(err == NULL);

    g_socket_bind(sock, bind_address, TRUE, &err);
    g_assert(err == NULL);

    //int fd = g_socket_get_fd(sock);
    //GIOChannel* channel = g_io_channel_unix_new(fd);
    //guint source = g_io_add_watch(channel, G_IO_IN,
    //                        (GIOFunc) test, NULL);
    //g_io_channel_unref(channel);
    GSource *source = g_socket_create_source (sock, G_IO_IN,
                                                      NULL);
    g_source_set_callback (source, (GSourceFunc)has_packet, NULL, NULL);

    GMainLoop *loop = g_main_loop_new(NULL, FALSE);
    g_source_attach(source ,g_main_loop_get_context(loop));

    g_main_loop_run(loop);
    g_main_loop_unref(loop);
}

我希望当有一个数据包到来时,只打印一个链接“有数据包”,但它会永远运行。您能帮我找出哪里出错了吗?

更新:我需要读取套接字中的数据。

gboolean has_packet(GIOChannel *source, GIOCondition condition, gpointer data)
{
    GSocket *sock = (GSocket *)data;
    char buf[65536];
    GSocketAddress *address = NULL;
    gssize bytes;
    GInputVector vector;
    GSocketControlMessage **messages;
    gint num_messages;

    GError *error = NULL;

    vector.buffer = buf;
    vector.size = 65536;
    bytes = g_socket_receive_message (sock,
                                      &address,
                                      &vector,
                                      1,
                                      &messages,
                                      &num_messages,
                                      NULL,
                                      NULL,
                                      &error);
    g_printf("has packet\n");
    g_printf("bytes = %zd\n", bytes);
    g_printf("num_message = %d\n", num_messages);
    return TRUE;
}

最佳答案

如果您只想调用一次回调,则应该从回调中返回 FALSE(或返回 G_SOURCE_REMOVE)。

此外,您可以使用 g_main_loop_run() 启动主循环,并且该循环将永远运行,直到调用 g_main_loop_quit() 为止。因此,您应该在某个时刻退出主循环(大概您希望它在收到数据包后退出,因此您应该在 has_packet() 中调用 g_main_loop_quit()

关于c++ - 回调 g_source_set 回调总是被调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25299337/

相关文章:

c++ - 为什么编译器会在提供无参数函数模板时尝试推断?

objective-c - 将一个空的 .c 文件添加到 Xcode Cocoa 项目会导致数千个错误

c - 如何将可变参数传递给接受可变参数的函数?

c - 中缀到后缀表达式

c++ - C++算术中的错误输出

C++11 线程 : sleep for a remaining time

c - 使用 glib 和 gtk+ 通过 USB 控制 ftdi 设备

python - 正在寻找一种更智能的方法将 Python 列表转换为 GList?

c++ - 通过 C++ main char** args 处理不同字符串编码的正确方法是什么?

c - "GNU libs vs Gnulib vs Gnome glib"困惑