基于Glib的网络实现示例

Glib简介

Glib库是C语言的好伙伴,整体设计的非常好!
但是,Glib的例子非常少. 不容易学习和借鉴.
这里的例子就是采用glib的高层网络API实现的TCP服务端和客户端.

以下实例都是正常运行的代码

TCP服务端代码实例:

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

gchar *buffer;

gboolean
network_read(GIOChannel *source,
            GIOCondition cond,
            gpointer data)
{
  GString *s = g_string_new(NULL);
    //error should be inited with NULL
  GError *error=NULL;
  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);
    g_object_unref(data);
    return FALSE;
    }
  else if (ret == G_IO_STATUS_EOF){
        g_print("finished\n");
        return FALSE;
    }else{
    g_print("Got: %s\n", s->str);

    //you should return this
    return TRUE;
    }

}

gboolean
new_connection(GSocketService *service,
              GSocketConnection *connection,
              GObject *source_object,
              gpointer user_data)
{
    // tell glib not to disconnect
    g_object_ref(connection);
  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);
  GIOChannel *channel = g_io_channel_unix_new(fd);
  //g_io_add_watch(channel, G_IO_IN, (GIOFunc) network_read, NULL);
  g_io_add_watch(channel, G_IO_IN, (GIOFunc) network_read, connection);
  return TRUE;
}

int main(int argc, char **argv) {
  GSocketService *service = g_socket_service_new();
  GInetAddress *address = g_inet_address_new_from_string("127.0.0.1");
  GSocketAddress *socket_address = g_inet_socket_address_new(address, 4000);
  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);

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

TCP客户端代码实例:

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

int main(int argc, char *argv[])
{

    GError *error = NULL;

    GSocketClient * client = g_socket_client_new();

    //GSocketConnection * connection = g_socket_client_connect_to_host (client,"10.9.27.15",5000,NULL,&error);
    GSocketConnection * connection = g_socket_client_connect_to_host (client,"localhost",9100,NULL,&error);


    if (error){
        g_error(error->message);
    }else{
        g_message("Connection ok");
    }

    guint8 buffer[]={170, 255, 255, 1, 204, 125, 128};
    guint8 incoming_buff[100]={0};

    GInputStream * in_stream = g_io_stream_get_input_stream(G_IO_STREAM(connection));
    GOutputStream * out_stream = g_io_stream_get_output_stream(G_IO_STREAM(connection));
    g_output_stream_write(out_stream, buffer, 7, NULL, &error);
    int incoming_num = g_input_stream_read(in_stream,incoming_buff,100,NULL,&error);

    if(error)
        g_error(error->message);
    else{
        int i=0; 
        printf("incoming:\n");
        for(;i<incoming_num;i++)
            printf("%hhX ",incoming_buff[i]);
        printf("\n");

        //g_message(incoming_buff);
    }

    return TRUE;

}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: glib2.0是常用的一个开源库。它提供了许多C语言编程接口,可以用于处理各种数据结构、文件I/O、字符串操作、进程控制等任务。下面提供一个简单的示例代码,演示如何使用glib2.0来读取一个文件的内容并计算出其中字母'A'出现的次数。 ```c #include <stdio.h> #include <stdlib.h> #include <glib.h> int main(int argc, char **argv) { GError *error = NULL; GIOChannel *channel; gchar *line = NULL; gsize length = 0; guint count = 0; if (argc != 2) { printf("Usage: %s filename\n", argv[0]); exit(1); } channel = g_io_channel_new_file(argv[1], "r", &error); if (channel == NULL) { fprintf(stderr, "g_io_channel_new_file error: %s\n", error->message); g_error_free(error); exit(1); } while (g_io_channel_read_line(channel, &line, &length, NULL, &error) == G_IO_STATUS_NORMAL) { gchar *p = line; while (*p) { if (*p == 'A') { count++; } p++; } g_free(line); } if (error != NULL) { fprintf(stderr, "g_io_channel_read_line error: %s\n", error->message); g_error_free(error); exit(1); } printf("Number of 'A': %u\n", count); g_io_channel_unref(channel); return 0; } ``` 上述代码首先判断传入的参数是否正确,申请内存用于处理文件,然后循环读取文件中的每一行,并在每一行中查找字母'A',最后输出'A'出现的次数。 总的来说,glib2.0库提供了非常丰富的函数和数据类型,可以很方便地完成各种任务。在实际使用中,可以参考官方文档和示例代码,进行深入学习和应用。 ### 回答2: glib2.0 是 Linux 平台上的一个基础库,提供了大量的功能,包括字符串、文件、内存操作、数据结构、线程等,让程序开发更加简单和高效。下面是一个简单的 glib2.0 示例代码: #include <stdio.h> #include <glib.h> int main(int argc, char *argv[]) { GString *str = g_string_new("Hello, "); g_string_append(str, "glib2.0"); printf("%s\n", str->str); g_string_free(str, TRUE); return 0; } 这个程序首先创建了一个 GString 对象,然后使用 g_string_append() 函数将字符串追加到 GString 中,最后打印出 GString 的内容并且释放 GString 占用的内存空间。 GString 是 glib2.0 中的一个字符串类型,功能类似于 C 语言中的 char 数组,但是 GString 可以动态地扩展内存空间,避免了计算空间大小的麻烦和内存溢出的问题。在这个程序中,使用 g_string_new() 函数创建一个新的 GString 对象,然后使用 g_string_append() 函数将字符串追加到 GString 中。最后,使用 g_string_free() 函数释放 GString 对象占用的内存空间。 以上是一个简单的 glib2.0 示例代码,使用 glib2.0 可以提高程序开发效率,让程序变得更加高效稳定。 ### 回答3: glib2.0 是一个非常常用的 C 语言开发库,它提供了许多通用的数据结构和函数,可以帮助我们写出高效的程序。下面是一个 glib2.0 的示例代码: ``` #include <glib.h> int main(int argc, char **argv) { // 创建一个 GList 对象来存储一些字符串 GList *list = NULL; list = g_list_append(list, "apple"); list = g_list_append(list, "banana"); list = g_list_append(list, "cherry"); // 遍历列表并打印每个字符串 GList *iter; for (iter = list; iter != NULL; iter = iter->next) { printf("%s\n", (char *)iter->data); } // 释放 GList 对象的内存 g_list_free(list); return 0; } ``` 这个示例代码演示了如何使用 glib2.0 创建一个 `GList` 对象来存储字符串,并遍历该列表来打印每个字符串。在程序末尾,通过调用 `g_list_free()` 函数来释放 `GList` 对象的内存。除了 `GList`,glib2.0 还提供了许多其他的数据结构和函数,例如哈希表、字符串处理等等,可以帮助我们更轻松地编写程序。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值