1 基本概念
IO Channels由GIOChannel结构描述,被GLib封装,必须通过公共函数来访问它的各个成员。每个IO Channel和一个文件或者类似于文件的对象相联系,在Linux上,IO Channel可以和打开文件描述符,套接字,管道如此以后就可以像访问文件一样操作IO Channels。
每个IO Channel上可以关联一些事件及其相应函数(watch),这个挂接在主循环上,于是乎,当事件来临之后,消息相应便可动作。
1.1 套接字(Socket)
对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。一个套接字就是网络上进程通信的一端,提供了应用层进程利用网络协议交换数据的机制。从所处的地位来讲,套接子上联应用进程,下联网络协议栈,是应用程序通过网络协议进行通信的接口,是应用程序与网络协议根进行交互的接口。
1.2 文件描述符(file descriptor)
内核利用文件描述符来访问文件。文件描述符是非负整数。打开现存文件或新建文件时候,内核会返回一个文件描述符。读写文件也需要使用文件描述符来制订待读写的文件。
1.3 计算机管道
1.3.1 基本概念
管道(pipe)是进程用来通讯的共享内存区域。一个进程往管道中写入信息,而其它的进程可以从管道中读出信息。如其名,管道是进程间数据交流的通路。
1.3.2 fork( )函数:创建新的进程
#include<unistd.h>
__pid_t fork (void);
- Return:一个是子进程返回0,第二个是父进程大于0,错误返回-1
1.3.3 pipe( )函数:建立管道
#include<unistd.h>
int pipe(int filedes[2]);
- pipe()会建立管道,并将文件描述词由参数filedes数组返回。
- filedes[0]为管道里的读取端。
- filedes[1]则为管道里的写入端。
2 GIO Channel相关函数总结
2.1 创建新的GIOChannel
适用于普通文件描述符、管道、套接字。
GIOChannel* g_io_channel_unix_new (int fd);
与系统无关的方式为文件创建通道。
GIOChannel* g_io_channel_new_file (const gchar *filename,
const gchar *mode,
GError **error);
通过GIOChannel得到文件描述符。
gint g_io_channel_unix_get_fd (GIOChannel *channel);
2.2 读取数据
2.2.1读取一行数据
除了一个gchar、GString存储字符串以为,还没有发现真正的区别。注意的是,每读取一行,指针指向的行跟着变化。
GIOStatus g_io_channel_read_line (GIOChannel *channel,
gchar **str_return,
gsize *length,
gsize *terminator_pos,
GError **error);
typedef enum
{
G_IO_STATUS_ERROR,
G_IO_STATUS_NORMAL,
G_IO_STATUS_EOF,
G_IO_STATUS_AGAIN
} GIOStatus;
GIOStatus g_io_channel_read_line_string (GIOChannel *channel,
GString *buffer,
gsize *terminator_pos,
GError **error);
2.2.2 读取文件中剩余数据
GIOStatus g_io_channel_read_to_end (GIOChannel *channel,
gchar **str_return,
gsize *length,
GError **error);
2.3 添加到事件循环
给定优先级
guint g_io_add_watch_full (GIOChannel *channel,
gint priority,
GIOCondition condition,
GIOFunc func,
gpointer user_data,
GDestroyNotify notify);
guint g_io_add_watch (GIOChannel *channel,
GIOCondition condition,
GIOFunc func,
gpointer user_data);
typedef enum /*< flags >*/
{
G_IO_IN GLIB_SYSDEF_POLLIN,/*有待读取资料*/
G_IO_OUT GLIB_SYSDEF_POLLOUT,/*可写入资料*/
G_IO_PRI GLIB_SYSDEF_POLLPRI,/*有待读取的紧急资料*/
G_IO_ERR GLIB_SYSDEF_POLLERR,/*发生错误*/
G_IO_HUP GLIB_SYSDEF_POLLHUP,/*连接挂断*/
G_IO_NVAL GLIB_SYSDEF_POLLNVAL/*无效请求*/
} GIOCondition;
2.4 关闭IO通道
如果flush为TRUE,则将刷新任何要写入的待处理数据。使用g_io_channel_unref()删除最后一个引用之前,不会释放该通道。
GIOStatus g_io_channel_shutdown (GIOChannel *channel,
gboolean flush,
GError **err);
参考1:本文代码参考博客
参考2:IO Channels
参考3:GIOChannel与Pipe
参考4:fork()+pipe() --> 父子进程间通过管道通信