【问题标题】:How to implement a tcp server in GTK based application using GIOChannel如何使用 GIOChannel 在基于 GTK 的应用程序中实现 tcp 服务器
【发布时间】:2017-07-19 10:09:03
【问题描述】:

我从 stackoverflow 本身获得了以下示例。

#include <glib.h>
#include <gio/gio.h>

gchar *buffer;

gboolean
network_write(GIOChannel *source,
            GIOCondition cond,
            gpointer data)
{
    return TRUE;
}
gboolean
network_read(GIOChannel *source,
            GIOCondition cond,
            gpointer data)
{
    GString *s = g_string_new(NULL);
    GError *error;
    g_print("Inside network_read function\n");
    GIOStatus ret = g_io_channel_read_line_string(source, s, NULL, &error);
    if (ret == G_IO_STATUS_ERROR)
        g_error ("Error reading: %s\n", error->message);
    else
        g_print("Got: %s\n", s->str);

    return TRUE;
}

gboolean
new_connection(GSocketService *service,
              GSocketConnection *connection,
              GObject *source_object,
              gpointer user_data)
{
  GSocketAddress *sockaddr = g_socket_connection_get_remote_address(connection, NULL);
  GInetAddress *addr = g_inet_socket_address_get_address(G_INET_SOCKET_ADDRESS(sockaddr));
  guint16 port = g_inet_socket_address_get_port(G_INET_SOCKET_ADDRESS(sockaddr));

  g_print("New Connection from %s:%d\n", g_inet_address_to_string(addr), port);

  GSocket *socket = g_socket_connection_get_socket(connection);

  gint fd = g_socket_get_fd(socket);
g_print("Naseeb fd: %d\n", fd);
  GIOChannel *channel = g_io_channel_unix_new(fd);
  if(!g_io_add_watch(channel, G_IO_IN, (GIOFunc) network_read, NULL))
  {
      g_print("Got Error while adding network_read\n");
  }
//  g_io_add_watch(channel, G_IO_OUT, (GIOFunc) network_write, NULL);
  return TRUE;
}

int main(int argc, char **argv) {
    g_type_init();
    GSocketService *service = g_socket_service_new();
    GInetAddress *address = g_inet_address_new_from_string("0.0.0.0");
    GSocketAddress *socket_address = g_inet_socket_address_new(address, 3001);
    g_socket_listener_add_address(G_SOCKET_LISTENER(service), socket_address, G_SOCKET_TYPE_STREAM,
            G_SOCKET_PROTOCOL_TCP, NULL, NULL, NULL);

    g_object_unref(socket_address);
    g_object_unref(address);
    g_socket_service_start(service);

    g_signal_connect(service, "incoming", G_CALLBACK(new_connection), NULL);
    g_socket_service_start(service);

    GMainLoop *loop = g_main_loop_new(NULL, FALSE);
    g_main_loop_run(loop);
    return 0;
}

使用此代码,我可以让客户端连接到服务器。我使用功能 new_connection

中打印的消息确认相同

但是当我从客户端发送数据时,回调 network_read 永远不会在服务器上被调用。虽然是客户端,但 send() API 返回值显示发送的总字节数。

1) 服务器端是否缺少任何 api。 2) 调用 network_write 的正确方法是什么?

【问题讨论】:

    标签: gtk3 glib gio


    【解决方案1】:

    你不应该使用GIOChannelnew_connection() 已经有一个连接,你可以使用stream = g_io_stream_get_input_stream (G_IO_STREAM (connection)); 来获取一个GInputStream 来读取。

    【讨论】:

    • 感谢您的回复。我尝试使用提到的 API,但仍然没有收到数据。 GInputStream *stream = g_io_stream_get_input_stream(G_IO_STREAM(connection)); gsize read_size; gboolean ret = g_input_stream_read_all(stream, recv_buf, 13, &amp;read_size, &amp;cancel, &amp;err); g_print("Naseeb g_input_stream_read_all return value: %d:%d\n", ret, read_size);
    • 另外,我想让我的应用程序作为 tcp 服务器,accept() 从客户端连接,并在数据以异步方式写入套接字时从套接字读取数据。
    猜你喜欢
    • 2012-01-06
    • 1970-01-01
    • 2016-01-25
    • 1970-01-01
    • 1970-01-01
    • 2010-09-07
    • 1970-01-01
    • 2021-05-10
    • 2019-02-10
    相关资源
    最近更新 更多