0
我想學習gio庫,特別是giostream和gthreadedsocketservice。我想編寫一個簡單的服務器:由gio庫實現的簡單線程服務器
- 每個傳入的連接將通過一個單獨的新線程
- 在客戶端進行處理,用戶鍵入一個字符串,它會被髮送到服務器;在服務器端收到字符串後立即將其顯示到stdout。
- 除非服務器或客戶端被終止,否則連接未關閉。即多個消息可以從客戶端發送到服務器而不需要多次連接。
我試過的代碼是: 客戶端:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include <gio/gio.h>
int main(int argc, char* argv[]){
GError* error = NULL;
GSocketConnection* connection = NULL;
GOutputStream* ostream = NULL;
GSocketClient* client = g_socket_client_new();
gchar message[1024];
connection = g_socket_client_connect_to_host(client, (gchar*)"localhost", 1500, NULL, &error);
if (error) {
g_error(error->message);
g_error_free(error);
return 1;
}
else g_print("Message: connected.\n");
while(TRUE){
scanf("%s", message);
ostream = g_io_stream_get_output_stream(G_IO_STREAM(connection));
g_output_stream_write(ostream, message, strlen(message), NULL, &error);
if (error) {
g_error(error->message);
g_error_free(error);
return 1;
}
}
g_print("Message: client terminated.\n");
return 0;
}
服務器端:
#include <glib.h>
#include <gio/gio.h>
gboolean run_callback(GThreadedSocketService*, GSocketConnection*, GObject*, gpointer);
int main(int argc, char **argv){
int port = 1500;
GError* error = NULL;
GMainLoop* loop = NULL;
GThreadedSocketService* service = NULL;
service = (GThreadedSocketService*)g_threaded_socket_service_new(-1);
g_socket_listener_add_inet_port((GSocketListener*)service, port, NULL, &error);
if (error != NULL) {g_error(error->message);}
g_signal_connect(service, "run", G_CALLBACK(run_callback), NULL);
g_socket_service_start((GSocketService*)service);
g_print("Message: server launched...\n");
loop = g_main_loop_new(NULL, FALSE);
g_main_loop_run(loop);
return 0;
}
gboolean run_callback(GThreadedSocketService* service, GSocketConnection* connection, GObject* source_object, gpointer user_data){
GInputStream* instream = NULL;
gchar message[1024];
GError* error = NULL;
instream = g_io_stream_get_input_stream(G_IO_STREAM(connection));
g_input_stream_read_all(instream, message, 1024, NULL, NULL, &error);
if (error != NULL) {
g_error(error->message);
g_error_free(error);
return FALSE;
}
g_print("Received: %s\n", message);
g_print("Message: connection terminated.\n");
if (error) g_error_free(error);
return FALSE;
}
問題是,當我測試了它,在客戶端我輸入3行:
aaa
bbb
ccc
但是服務器上沒有顯示任何內容側。只有當我退出客戶端,服務器屏幕上它顯示:
aaabbbccc
但我想要的是當我輸入「AAA」,進入,它會立即顯示在服務器屏幕上。
任何想法出錯的地方?
經過測試,它的工作原理。我可以問一下,當我運行一個循環時,我在其中調用g_input_stream_read(),並且此刻沒有輸入,該函數是否會返回並繼續循環,直到出現一些輸入(類似於輪詢),還是阻塞這個線程在等待輸入嗎? – robinchm
@robinchm套接字默認爲*阻塞*,並且這在鏈中一路上升,這意味着當您從阻塞套接字讀取時,讀取調用(無論它是什麼函數)應該阻塞,直到有東西要讀取。 –
非常感謝!因爲gio在他們的手冊中也提供了異步IO和不同類型的套接字服務,但沒有例子來說明它們的用法,所以我努力學習它很多。 – robinchm