我想創建一個服務器和客戶端應用程序,通過使用GIO的套接字進行通信。 GSocketService和GSocketClient似乎是完美的,但不幸的是,我找不到一些教程或示例代碼(GLib,GIO,...新手都能理解)。有人知道一些好的資源,或者可以在這裏發佈示例代碼嗎?GIO套接字服務器/客戶端示例
回答
我終於設法使用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,所以仔細檢查我的代碼在使用之前。
感謝您分享此內容。這將是GIO新人的寶貴資源。參考文檔很好,但缺乏示例。 – noisebleed 2012-04-10 09:15:21
@noisebleed:對這裏的文檔有相同的看法。 – drakide 2012-04-11 08:27:54
實際上,你可以使用這樣一個命令「echo anyword | nc localhost 1500」作爲客戶端來證明服務器是否工作。 – mxi1 2014-04-08 05:37:09
從傳入的回調不應該阻止,從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;
}
- 1. 精煉服務器/客戶端TCP套接字示例
- 2. PHP套接字服務器/客戶端
- 3. 客戶端服務器udp套接字
- 4. 套接字java客戶端服務器
- 5. 客戶端 - 服務器套接字
- 6. 服務器/客戶端套接字
- 7. 客戶端服務器套接字C#
- 8. Python服務器客戶端套接字
- 9. Java套接字客戶端/服務器
- 10. 由於關閉套接字,服務器回覆客戶端消息失敗 - Java客戶端 - 服務器示例
- 11. C套接字服務器,Java套接字客戶端:阻塞!
- 12. Python套接字客戶端到Java套接字服務器
- 13. 嘗試連接到服務器2秒的客戶端套接字示例
- 14. C#套接字TCP客戶端/服務
- 15. WPF異步套接字服務器/客戶端推薦示例/庫
- 16. 客戶端 - 服務器Unix套接字和端口轉發
- 17. 使用多個端口的套接字客戶端/服務器
- 18. Java套接字。服務器端與客戶端通訊
- 19. Java客戶端/服務器套接字端口分配
- 20. 無法使用套接字連接客戶端到服務器
- 21. 接受客戶端的Java服務器套接字
- 22. php套接字服務器檢查客戶端是否連接
- 23. 服務器/客戶端套接字連接
- 24. 同時關閉服務器和客戶端套接字連接
- 25. Android客戶端套接字無法連接到服務器
- 26. Java雙向套接字連接(服務器/客戶端)
- 27. 客戶端和服務器Android套接字連接
- 28. 無法連接Java套接字服務器和客戶端
- 29. 套接字 - Android客戶端到C#服務器連接
- 30. 讓套接字服務器接受多個客戶端
你取得任何進展?我正在尋找同樣的事情。除了[API](http://developer.gnome.org/gio/stable/highlevel-socket.html)和[SO回答](http://stackoverflow.com/a/2145259/545442)我還沒有'什麼都沒發現。 – noisebleed 2012-04-09 15:33:02
@noisebleed:是的,我確實取得了進展。我其實不明白爲什麼我第一次嘗試時無法創建服務器和客戶端。可能我不應該嘗試同時學習C,glib和OGRE。 – drakide 2012-04-10 08:33:52