Я хотел бы создать серверное и клиентское приложение, которые взаимодействуют через сокеты с использованием GIO. GSocketService и GSocketClient кажутся идеальными для этой цели, но, к сожалению, я не смог найти какой-либо учебник или пример кода (который может понять новичок GLib, GIO,...). Кто-нибудь знает хорошие ресурсы или может разместить пример кода здесь?
пример GIO socket-server/-client
comment
Вы добились какого-либо прогресса? Я ищу то же самое. Помимо API и этого ТАК ответьте Я ничего не нашел.
- person noisebleed   schedule 09.04.2012
comment
@noisebleed: Да, я действительно добился прогресса. На самом деле я не понимаю, почему я не смог создать и сервер, и клиент с первой попытки. Наверное, мне не стоит одновременно изучать C, glib и OGRE.
- person drakide   schedule 10.04.2012
Ответы (2)
Наконец-то мне удалось создать простой сервер и клиент с помощью 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;
}
Обратите внимание, что я все еще новичок в glib, gio и даже C, поэтому дважды проверьте мой код, прежде чем использовать его.
person
drakide
schedule
10.04.2012
Спасибо, что поделились этим. Это будет бесценный ресурс для новичков GIO. Справочная документация хороша, но примеров не хватает.
- person noisebleed; 10.04.2012
@noisebleed: такое же мнение о документации здесь.
- person drakide; 11.04.2012
на самом деле, вы можете использовать одну такую команду echo anyword |nc localhost 1500 в качестве клиента, чтобы проверить, работает ли сервер.
- person mxi1; 08.04.2014
Было бы здорово, если бы вы могли прочитать ответ с сервера.
- person diega; 29.05.2016
неопределенная ссылка на `g_io_stream_get_type'| ПОМОЩЬ!
- person Samuel; 22.11.2016
Добавить
pkg-config --cflags --libs glib-2.0 gio-2.0
- person Samuel; 22.11.2016
Обратный вызов от входящего не должен блокироваться, из документации 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;
}
person
Fujii
schedule
13.08.2014