I am trying to learn gio library, especially the giostream and gthreadedsocketservice. I want to write a simple server that:
The code I tried is: Client-side:
#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;
}
Server-side:
#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;
}
The problem is when I tested it out, on client side I typed three lines:
aaa
bbb
ccc
But nothing is shown on the server side. Only when I exit the client, on the server screen it shows:
aaabbbccc
But what I wanted was when I type "aaa" and entered, it immediately shows up on the server screen.
Any idea on where it goes wrong?
The problem is that you use g_input_stream_read_all
. Notice the suffix all
in the name? It means that it will attempt to read the size you pass to it, only returning when it has received all those bytes or there is an error or disconnection.
Instead use e.g. g_input_stream_read
in a loop.