2012-03-01 2 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

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

을이 해당 클라이언트입니다 : 나는 아직도 입심에 새로운 오전,하지만

#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

+0

@noisebleed : 여기에 대한 문서에 대한 의견이 같습니다. – drakide

+0

실제로 "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; 
}