(root)/
glib-2.79.0/
gio/
tests/
send-data.c
       1  #include <gio/gio.h>
       2  #include <string.h>
       3  #include <stdio.h>
       4  
       5  GMainLoop *loop;
       6  
       7  int cancel_timeout = 0;
       8  int io_timeout = 0;
       9  gboolean async = FALSE;
      10  gboolean graceful = FALSE;
      11  gboolean verbose = FALSE;
      12  static GOptionEntry cmd_entries[] = {
      13    {"cancel", 'c', 0, G_OPTION_ARG_INT, &cancel_timeout,
      14     "Cancel any op after the specified amount of seconds", NULL},
      15    {"async", 'a', 0, G_OPTION_ARG_NONE, &async,
      16     "Use async ops", NULL},
      17    {"graceful-disconnect", 'g', 0, G_OPTION_ARG_NONE, &graceful,
      18     "Use graceful disconnect", NULL},
      19    {"timeout", 't', 0, G_OPTION_ARG_INT, &io_timeout,
      20     "Time out socket I/O after the specified number of seconds", NULL},
      21    {"verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose,
      22     "Verbose debugging output", NULL},
      23    G_OPTION_ENTRY_NULL
      24  };
      25  
      26  static gpointer
      27  cancel_thread (gpointer data)
      28  {
      29    GCancellable *cancellable = data;
      30  
      31    g_usleep (1000*1000*cancel_timeout);
      32    g_print ("Cancelling\n");
      33    g_cancellable_cancel (cancellable);
      34    return NULL;
      35  }
      36  
      37  static char *
      38  socket_address_to_string (GSocketAddress *address)
      39  {
      40    GInetAddress *inet_address;
      41    char *str, *res;
      42    int port;
      43  
      44    inet_address = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (address));
      45    str = g_inet_address_to_string (inet_address);
      46    port = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (address));
      47    res = g_strdup_printf ("%s:%d", str, port);
      48    g_free (str);
      49    return res;
      50  }
      51  
      52  static void
      53  async_cb (GObject *source_object,
      54  	  GAsyncResult *res,
      55  	  gpointer user_data)
      56  {
      57    GAsyncResult **resp = user_data;
      58    *resp = g_object_ref (res);
      59    g_main_loop_quit (loop);
      60  }
      61  
      62  static void
      63  socket_client_event (GSocketClient *client,
      64  		     GSocketClientEvent event,
      65  		     GSocketConnectable *connectable,
      66  		     GSocketConnection *connection)
      67  {
      68    static GEnumClass *event_class;
      69    gint64 now_us;
      70  
      71    if (!event_class)
      72      event_class = g_type_class_ref (G_TYPE_SOCKET_CLIENT_EVENT);
      73  
      74    now_us = g_get_real_time ();
      75    g_print ("%" G_GINT64_FORMAT " GSocketClient => %s [%s]\n",
      76  	  now_us,
      77  	  g_enum_get_value (event_class, event)->value_nick,
      78  	  connection ? G_OBJECT_TYPE_NAME (connection) : "");
      79  }
      80  
      81  int
      82  main (int argc, char *argv[])
      83  {
      84    GOptionContext *context;
      85    GSocketClient *client;
      86    GSocketConnection *connection;
      87    GSocketAddress *address;
      88    GCancellable *cancellable;
      89    GOutputStream *out;
      90    GError *error = NULL;
      91    char buffer[1000];
      92  
      93    context = g_option_context_new (" <hostname>[:port] - send data to tcp host");
      94    g_option_context_add_main_entries (context, cmd_entries, NULL);
      95    if (!g_option_context_parse (context, &argc, &argv, &error))
      96      {
      97        g_printerr ("%s: %s\n", argv[0], error->message);
      98        return 1;
      99      }
     100  
     101    if (argc != 2)
     102      {
     103        g_printerr ("%s: %s\n", argv[0], "Need to specify hostname");
     104        return 1;
     105      }
     106  
     107    if (async)
     108      loop = g_main_loop_new (NULL, FALSE);
     109  
     110    if (cancel_timeout)
     111      {
     112        GThread *thread;
     113        cancellable = g_cancellable_new ();
     114        thread = g_thread_new ("cancel", cancel_thread, cancellable);
     115        g_thread_unref (thread);
     116      }
     117    else
     118      {
     119        cancellable = NULL;
     120      }
     121  
     122    client = g_socket_client_new ();
     123    if (io_timeout)
     124      g_socket_client_set_timeout (client, io_timeout);
     125    if (verbose)
     126      g_signal_connect (client, "event", G_CALLBACK (socket_client_event), NULL);
     127  
     128    if (async)
     129      {
     130        GAsyncResult *res;
     131        g_socket_client_connect_to_host_async (client, argv[1], 7777,
     132  					     cancellable, async_cb, &res);
     133        g_main_loop_run (loop);
     134        connection = g_socket_client_connect_to_host_finish (client, res, &error);
     135        g_object_unref (res);
     136      }
     137    else
     138      {
     139        connection = g_socket_client_connect_to_host (client,
     140  						    argv[1],
     141  						    7777,
     142  						    cancellable, &error);
     143      }
     144    if (connection == NULL)
     145      {
     146        g_printerr ("%s can't connect: %s\n", argv[0], error->message);
     147        return 1;
     148      }
     149    g_object_unref (client);
     150  
     151    address = g_socket_connection_get_remote_address (connection, &error);
     152    if (!address)
     153      {
     154        g_printerr ("Error getting remote address: %s\n",
     155  		  error->message);
     156        return 1;
     157      }
     158    g_print ("Connected to address: %s\n",
     159  	   socket_address_to_string (address));
     160    g_object_unref (address);
     161  
     162    if (graceful)
     163      g_tcp_connection_set_graceful_disconnect (G_TCP_CONNECTION (connection), TRUE);
     164  
     165    out = g_io_stream_get_output_stream (G_IO_STREAM (connection));
     166  
     167    while (fgets(buffer, sizeof (buffer), stdin) != NULL)
     168      {
     169        /* FIXME if (async) */
     170        if (!g_output_stream_write_all (out, buffer, strlen (buffer),
     171  				      NULL, cancellable, &error))
     172  	{
     173  	  g_warning ("send error: %s",  error->message);
     174  	  g_error_free (error);
     175  	  error = NULL;
     176  	}
     177      }
     178  
     179    g_print ("closing stream\n");
     180    if (async)
     181      {
     182        GAsyncResult *res;
     183        g_io_stream_close_async (G_IO_STREAM (connection),
     184  			       0, cancellable, async_cb, &res);
     185        g_main_loop_run (loop);
     186        if (!g_io_stream_close_finish (G_IO_STREAM (connection),
     187  				     res, &error))
     188  	{
     189  	  g_object_unref (res);
     190  	  g_warning ("close error: %s",  error->message);
     191  	  return 1;
     192  	}
     193        g_object_unref (res);
     194      }
     195    else
     196      {
     197        if (!g_io_stream_close (G_IO_STREAM (connection), cancellable, &error))
     198  	{
     199  	  g_warning ("close error: %s",  error->message);
     200  	  return 1;
     201  	}
     202      }
     203  
     204    g_object_unref (connection);
     205  
     206    return 0;
     207  }