!!! IOチャネル * ファイルやパイプ、ソケットを利用するための汎用的な方法 * メイン・イベント・ループへ統合できる ** 「通信が来たら、関数を呼び出す」みたいなプログラムが書ける !! チャネルの作成 8< GIOChannel* g_io_channel_new_file (gchar *filename, gchar *mode, GError **error); >8 ** [g_io_channel_new_file|https://developer.gnome.org/glib/2.34/glib-IO-Channels.html#g-io-channel-new-file] ** エラー時は NULL が返される。 8< GIOChannel* g_io_channel_unix_new (int fd); >8 ** [g_io_channel_unix_new|https://developer.gnome.org/glib/2.34/glib-IO-Channels.html#g-io-channel-unix-new] 8< void g_io_channel_set_close_on_unref (GIOChannel *channel, gboolean do_close); >8 ** [g_io_channel_set_close_on_unref|https://developer.gnome.org/glib/2.34/glib-IO-Channels.html#g-io-channel-set-close-on-unref] 8< GIOStatus g_io_channel_set_encoding (GIOChannel *channel, const gchar *encoding, GError **error); >8 ** [g_io_channel_set_encoding|https://developer.gnome.org/glib/2.34/glib-IO-Channels.html#g-io-channel-set-encoding] 8< GIOStatus g_io_channel_set_flags (GIOChannel *channel, GIOFlags flags, GError **error); >8 ** [g_io_channel_set_flags|https://developer.gnome.org/glib/2.34/glib-IO-Channels.html#g-io-channel-set-flags] !! チャネルをメイン・イベント・ループへ追加 8< guint g_io_add_watch (GIOChannel *channel, GIOCondition condition, GIOFunc func, gpointer user_data); >8 ** [g_io_add_watch|https://developer.gnome.org/glib/2.34/glib-IO-Channels.html#g-io-add-watch] !! チャネルの使用 8< GIOStatus g_io_channel_read_chars (GIOChannel *channel, gchar *buf, gsize count, gsize *bytes_read, GError **error); >8 ** [g_io_channel_read_chars|https://developer.gnome.org/glib/2.34/glib-IO-Channels.html#g-io-channel-read-chars] 8< GIOStatus g_io_channel_read_line (GIOChannel *channel, gchar **str_return, gsize *length, gsize *terminator_pos, GError **error); >8 ** [g_io_channel_read_line|https://developer.gnome.org/glib/2.34/glib-IO-Channels.html#g-io-channel-read-line] 8< GIOStatus g_io_channel_read_to_end (GIOChannel *channel, gchar **str_return, gsize *length, GError **error); >8 ** [g_io_channel_read_to_end|https://developer.gnome.org/glib/2.34/glib-IO-Channels.html#g-io-channel-read-to-end] 8< GIOStatus g_io_channel_write_chars (GIOChannel *channel, const gchar *buf, gssize count, gsize *bytes_written, GError **error); >8 ** [g_io_channel_write_chars|https://developer.gnome.org/glib/2.34/glib-IO-Channels.html#g-io-channel-write-chars] ! UDPサーバプログラム * チャネルの作成と追加 ** my_input_event_server 8< /* サーバソケットを作成 */ if((s_in = ServerSetup(portnumber)) < 0) { return make_error_message("Error: ServerSetup"); } /* ソケットに関数を結び付けメイン・イベント・ループに追加 */ if(!add_watch(s_in, (GIOFunc)read_client, g_drawable)) { return make_error_message("Error: AddWatch"); } >8 ** add_watch 8< /* ソケットからIOチャネルを作成 */ channel = g_io_channel_unix_new(sin); /* チャネルがなくなるときソケットも閉じる */ g_io_channel_set_close_on_unref(channel, TRUE); /* チャネルの送受信データのエンコードをなし(バイナリ用)に デフォルトはUTF-8 */ g_io_channel_set_encoding(channel, NULL, NULL); /* チャネルを非ブロックモードに */ g_io_channel_set_flags(channel, G_IO_FLAG_NONBLOCK, &error); /* メイン・イベント・ループにチャネル channel に データが届いたり(G_IO_IN)、ハングアップ(G_IO_HUP)したら 関数 func を data を引数として呼び出すように登録 */ g_io_add_watch(channel, G_IO_IN | G_IO_HUP, func, data); >8 * チャネルの使用 ** read_client 8< status = g_io_channel_read_chars(channel, (gchar *)&event, sizeof(event), &size, &error); switch(status) { case G_IO_STATUS_NORMAL: /* 読み込み正常 */ /* 何かやりたいことを書く */ return TRUE; case G_IO_STATUS_ERROR: /* 読み込み失敗 */ g_printerr("Error reading fd from client: %s\n", error->message); /* この関数をループから外す */ return FALSE; default: return FALSE; } >8