ソフトウェア設計及び演習2017
GDK2017::IOチャネル
IOチャネル
- ファイルやパイプ、ソケットを利用するための汎用的な方法
- メイン・イベント・ループへ統合できる
- 「通信が来たら、関数を呼び出す」みたいなプログラムが書ける
チャネルの作成
GIOChannel* g_io_channel_new_file (gchar *filename, gchar *mode, GError **error);
-
g_io_channel_new_file
- エラー時は NULL が返される。
GIOChannel* g_io_channel_unix_new (int fd);
void g_io_channel_set_close_on_unref (GIOChannel *channel, gboolean do_close);
GIOStatus g_io_channel_set_encoding (GIOChannel *channel, const gchar *encoding, GError **error);
GIOStatus g_io_channel_set_flags (GIOChannel *channel, GIOFlags flags, GError **error);
チャネルをメイン・イベント・ループへ追加
guint g_io_add_watch (GIOChannel *channel, GIOCondition condition, GIOFunc func, gpointer user_data);
チャネルの使用
GIOStatus g_io_channel_read_chars (GIOChannel *channel, gchar *buf, gsize count, gsize *bytes_read, GError **error);
GIOStatus g_io_channel_read_line (GIOChannel *channel, gchar **str_return, gsize *length, gsize *terminator_pos, GError **error);
GIOStatus g_io_channel_read_to_end (GIOChannel *channel, gchar **str_return, gsize *length, GError **error);
GIOStatus g_io_channel_write_chars (GIOChannel *channel, const gchar *buf, gssize count, gsize *bytes_written, GError **error);
サーバプログラム
input_event サンプルでは,「クライアントウィンドウ上で起こったイベント」を,そのままサーバに送っています.(GdkEvent構造体そのものを,バイナリデータとして送受信します)
- チャネルの作成と追加
- my_input_event_server
/* サーバソケットを作成 */ 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"); }
- add_watch
/* ソケットから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);
- チャネルの使用
- read_client
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; }
最終更新日:2017/04/03 09:14:22