Glibベースのネットワーク実装例


Glibの概要


GlibライブラリはC言語の良いパートナーで、全体の設計はとても良いです!しかし、Glibの例は非常に少ない.勉強と参考になりにくい.ここでの例はglibの高レベルネットワークAPIを用いる実現されるTCPサービス側とクライアントである.
次の例は、正常に動作するコードです.

TCPサービス側コード例:

#include 
#include 

gchar *buffer;

gboolean
network_read(GIOChannel *source,
            GIOCondition cond,
            gpointer data)
{
  GString *s = g_string_new(NULL);
    //error should be inited with NULL
  GError *error=NULL;
  GIOStatus ret = g_io_channel_read_line_string(source, s, NULL, &error);
  if (ret == G_IO_STATUS_ERROR){
    g_error ("Error reading: %s
"
, error->message); g_object_unref(data); return FALSE; } else if (ret == G_IO_STATUS_EOF){ g_print("finished
"
); return FALSE; }else{ g_print("Got: %s
"
, s->str); //you should return this return TRUE; } } gboolean new_connection(GSocketService *service, GSocketConnection *connection, GObject *source_object, gpointer user_data) { // tell glib not to disconnect g_object_ref(connection); GSocketAddress *sockaddr = g_socket_connection_get_remote_address(connection, NULL); GInetAddress *addr = g_inet_socket_address_get_address(G_INET_SOCKET_ADDRESS(sockaddr)); guint16 port = g_inet_socket_address_get_port(G_INET_SOCKET_ADDRESS(sockaddr)); g_print("New Connection from %s:%d
"
, g_inet_address_to_string(addr), port); GSocket *socket = g_socket_connection_get_socket(connection); gint fd = g_socket_get_fd(socket); GIOChannel *channel = g_io_channel_unix_new(fd); //g_io_add_watch(channel, G_IO_IN, (GIOFunc) network_read, NULL); g_io_add_watch(channel, G_IO_IN, (GIOFunc) network_read, connection); return TRUE; } int main(int argc, char **argv) { GSocketService *service = g_socket_service_new(); GInetAddress *address = g_inet_address_new_from_string("127.0.0.1"); GSocketAddress *socket_address = g_inet_socket_address_new(address, 4000); g_socket_listener_add_address(G_SOCKET_LISTENER(service), socket_address, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_TCP, NULL, NULL, NULL); g_object_unref(socket_address); g_object_unref(address); g_socket_service_start(service); g_signal_connect(service, "incoming", G_CALLBACK(new_connection), NULL); GMainLoop *loop = g_main_loop_new(NULL, FALSE); g_main_loop_run(loop); }

TCPクライアントコード例:

#include 
#include 
#include 
#include 

int main(int argc, char *argv[])
{

    GError *error = NULL;

    GSocketClient * client = g_socket_client_new();

    //GSocketConnection * connection = g_socket_client_connect_to_host (client,"10.9.27.15",5000,NULL,&error);
    GSocketConnection * connection = g_socket_client_connect_to_host (client,"localhost",9100,NULL,&error);


    if (error){
        g_error(error->message);
    }else{
        g_message("Connection ok");
    }

    guint8 buffer[]={170, 255, 255, 1, 204, 125, 128};
    guint8 incoming_buff[100]={0};

    GInputStream * in_stream = g_io_stream_get_input_stream(G_IO_STREAM(connection));
    GOutputStream * out_stream = g_io_stream_get_output_stream(G_IO_STREAM(connection));
    g_output_stream_write(out_stream, buffer, 7, NULL, &error);
    int incoming_num = g_input_stream_read(in_stream,incoming_buff,100,NULL,&error);

    if(error)
        g_error(error->message);
    else{
        int i=0; 
        printf("incoming:
"
); for(;iprintf("%hhX ",incoming_buff[i]); printf("
"
); //g_message(incoming_buff); } return TRUE; }