2012-03-01 32 views
7

我想創建一個服務器和客戶端應用程序,通過使用GIO的套接字進行通信。 GSocketService和GSocketClient似乎是完美的,但不幸的是,我找不到一些教程或示例代碼(GLib,GIO,...新手都能理解)。有人知道一些好的資源,或者可以在這裏發佈示例代碼嗎?GIO套接字服務器/客戶端示例

+0

你取得任何進展?我正在尋找同樣的事情。除了[API](http://developer.gnome.org/gio/stable/highlevel-socket.html)和[SO回答](http://stackoverflow.com/a/2145259/545442)我還沒有'什麼都沒發現。 – noisebleed 2012-04-09 15:33:02

+0

@noisebleed:是的,我確實取得了進展。我其實不明白爲什麼我第一次嘗試時無法創建服務器和客戶端。可能我不應該嘗試同時學習C,glib和OGRE。 – drakide 2012-04-10 08:33:52

回答

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; 
} 

,這爲相應客戶:

#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; 
} 

不過請注意,我還是新的巧舌如簧,吉奧甚至C,所以仔細檢查我的代碼在使用之前。

+0

感謝您分享此內容。這將是GIO新人的寶貴資源。參考文檔很好,但缺乏示例。 – noisebleed 2012-04-10 09:15:21

+0

@noisebleed:對這裏的文檔有相同的看法。 – drakide 2012-04-11 08:27:54

+0

實際上,你可以使用這樣一個命令「echo anyword | nc localhost 1500」作爲客戶端來證明服務器是否工作。 – mxi1 2014-04-08 05:37:09

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; 
} 
相關問題