2012-03-01 31 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; 
} 
相关问题