2012-03-01 7 views
7

GIOを使用してソケット経由で通信するサーバとクライアントアプリケーションを作成したいと思います。 GSocketServiceとGSocketClientはこの目的には完璧なようですが、残念ながらチュートリアルやサンプルコード(GLib、GIO、newbieが理解できるもの)を見つけることができませんでした。誰かが良いリソースを知っているのですか、ここにサンプルコードを投稿できますか?GIOソケットサーバ/クライアント例

+0

あなたはどんな進歩を遂げるましたか?私は同じことを探しています。 [API](http://developer.gnome.org/gio/stable/highlevel-socket.html)と[SO答え](http://stackoverflow.com/a/2145259/545442)のほかに、何かを見つけた。 – noisebleed

+0

@noisebleed:はい、本当に進歩しました。私は実際に私が最初の試行でサーバとクライアントの両方を作成できなかった理由を実際には知りません。おそらく、私はC、glib、OGREを同時に学習しようとすべきではありません。 – drakide

答えて

17

最終的に、glibとgioを使用して単純なサーバーとクライアントの両方を作成することができました。
私のサーバーは、次のようになります。

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

/* this function will get called everytime a client attempts to connect */ 
gboolean 
incoming_callback (GSocketService *service, 
        GSocketConnection *connection, 
        GObject *source_object, 
        gpointer user_data) 
{ 
    g_print("Received Connection from client!\n"); 
    GInputStream * istream = g_io_stream_get_input_stream (G_IO_STREAM (connection)); 
    gchar message[1024]; 
    g_input_stream_read (istream, 
         message, 
         1024, 
         NULL, 
         NULL); 
    g_print("Message was: \"%s\"\n", message); 
    return FALSE; 
} 

int 
main (int argc, char **argv) 
{ 
    /* initialize glib */ 
    g_type_init(); 

    GError * error = NULL; 

    /* create the new socketservice */ 
    GSocketService * service = g_socket_service_new(); 

    /* connect to the port */ 
    g_socket_listener_add_inet_port ((GSocketListener*)service, 
            1500, /* your port goes here */ 
            NULL, 
            &error); 

    /* don't forget to check for errors */ 
    if (error != NULL) 
    { 
     g_error (error->message); 
    } 

    /* listen to the 'incoming' signal */ 
    g_signal_connect (service, 
        "incoming", 
        G_CALLBACK (incoming_callback), 
        NULL); 

    /* start the socket service */ 
    g_socket_service_start (service); 

    /* enter mainloop */ 
    g_print ("Waiting for client!\n"); 
    GMainLoop *loop = g_main_loop_new(NULL, FALSE); 
    g_main_loop_run(loop); 
    return 0; 
} 

と、これは、対応するクライアントです:私はまだ口が達者する新しい、GIO、さらにはCです、そう二重の私のコードをチェックしていること、しかし

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

int 
main (int argc, char *argv[]) 
{ 
    /* initialize glib */ 
    g_type_init(); 

    GError * error = NULL; 

    /* create a new connection */ 
    GSocketConnection * connection = NULL; 
    GSocketClient * client = g_socket_client_new(); 

    /* connect to the host */ 
    connection = g_socket_client_connect_to_host (client, 
               (gchar*)"localhost", 
               1500, /* your port goes here */ 
               NULL, 
               &error); 

    /* don't forget to check for errors */ 
    if (error != NULL) 
    { 
     g_error (error->message); 
    } 
    else 
    { 
     g_print ("Connection successful!\n"); 
    } 

    /* use the connection */ 
    GInputStream * istream = g_io_stream_get_input_stream (G_IO_STREAM (connection)); 
    GOutputStream * ostream = g_io_stream_get_output_stream (G_IO_STREAM (connection)); 
    g_output_stream_write (ostream, 
          "Hello server!", /* your message goes here */ 
          13, /* length of your message */ 
          NULL, 
          &error); 
    /* don't forget to check for errors */ 
    if (error != NULL) 
    { 
     g_error (error->message); 
    } 
    return 0; 
} 

注意それを使用する前に。

+0

これを共有していただきありがとうございます。 GIO初心者のための貴重なリソースとなるでしょう。リファレンスドキュメントは良いですが、例が欠けています。 – noisebleed

+0

@noisebleed:こちらのドキュメントに関する意見はこちら。 – drakide

+0

実際には、このような1つのコマンド "echo anyword | nc localhost 1500"をクライアントとして使用して、サーバが動作しているかどうかを証明することができます。 – mxi1

5

gioのドキュメントからは、「ハンドラは接続の処理を開始する必要がありますが、ブロックすることはできず、本質的に非同期操作を使用する必要があります。

非同期バージョンで接続に問題がありました。ユーザーが参照する必要があります。そうでない場合は、着信コールバックが戻った後に接続が閉じられます。

前に与えられた例に基づいて、ブロックされません、サーバーの完全な例:

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

#define BLOCK_SIZE 1024 
#define PORT 2345 

struct ConnData { 
    GSocketConnection *connection; 
    char message[BLOCK_SIZE]; 
}; 

void message_ready (GObject * source_object, 
    GAsyncResult *res, 
    gpointer user_data) 
{ 
    GInputStream *istream = G_INPUT_STREAM (source_object); 
    GError *error = NULL; 
    struct ConnData *data = user_data; 
    int count; 

    count = g_input_stream_read_finish (istream, 
     res, 
     &error); 

    if (count == -1) { 
    g_error ("Error when receiving message"); 
    if (error != NULL) { 
     g_error ("%s", error->message); 
     g_clear_error (&error); 
    } 
    } 
    g_message ("Message was: \"%s\"\n", data->message); 
    g_object_unref (G_SOCKET_CONNECTION (data->connection)); 
    g_free (data); 
} 

static gboolean 
incoming_callback (GSocketService *service, 
    GSocketConnection * connection, 
    GObject * source_object, 
    gpointer user_data) 
{ 
    g_message ("Received Connection from client!\n"); 
    GInputStream *istream = g_io_stream_get_input_stream (G_IO_STREAM (connection)); 
    struct ConnData *data = g_new (struct ConnData, 1); 

    data->connection = g_object_ref (connection); 

    g_input_stream_read_async (istream, 
     data->message, 
     sizeof (data->message), 
     G_PRIORITY_DEFAULT, 
     NULL, 
     message_ready, 
     data); 
    return FALSE; 
} 

int main() 
{ 
    GSocketService *service; 
    GError *error = NULL; 
    gboolean ret; 

    service = g_socket_service_new(); 
    ret = g_socket_listener_add_inet_port (G_SOCKET_LISTENER (service), 
     PORT, NULL, &error); 

    if (ret && error != NULL) 
    { 
    g_error ("%s", error->message); 
    g_clear_error (&error); 
    return 1; 
    } 

    g_signal_connect (service, 
     "incoming", 
     G_CALLBACK (incoming_callback), 
     NULL); 

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

    /* Stop service when out of the main loop*/ 
    g_socket_service_stop (service); 
    return 0; 
} 
関連する問題