gio.cpp 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. #define GI_INLINE 1
  2. #include <gio/gio.hpp>
  3. #include <iostream>
  4. namespace GLib = gi::repository::GLib;
  5. namespace Gio = gi::repository::Gio;
  6. const std::string localhost("127.0.0.1");
  7. static GLib::MainLoop loop;
  8. // many calls here support GError
  9. // so typically will throw here instead
  10. // (unless GError output is explicitly requested in call signature)
  11. static bool
  12. receive(Gio::Socket s, GLib::IOCondition /*cond*/)
  13. {
  14. guint8 buffer[1024] = {
  15. 0,
  16. };
  17. Gio::SocketAddress a;
  18. int count = gi::expect(s.receive_from(&a, buffer, sizeof(buffer)));
  19. if (count > 0) {
  20. // let's see where it came from
  21. std::string origin("someone");
  22. auto ia = gi::object_cast<Gio::InetSocketAddress>(a);
  23. if (ia) {
  24. origin = ia.get_address().to_string();
  25. origin += ":";
  26. origin += std::to_string(ia.get_port());
  27. }
  28. std::cout << origin << " said " << (char *)buffer << std::endl;
  29. // quit when idle
  30. GLib::idle_add([]() {
  31. loop.quit();
  32. return GLib::SOURCE_REMOVE_;
  33. });
  34. }
  35. return true;
  36. }
  37. Gio::Socket
  38. open(bool listen)
  39. {
  40. auto socket = gi::expect(Gio::Socket::new_(Gio::SocketFamily::IPV4_,
  41. Gio::SocketType::DATAGRAM_, Gio::SocketProtocol::DEFAULT_));
  42. auto address = Gio::InetSocketAddress::new_from_string(localhost, 0);
  43. socket.bind(address, false);
  44. socket.set_blocking(false);
  45. if (listen) {
  46. // runtime introspection has a hard time here,
  47. // but with a bit of extra information, we can keep going
  48. GLib::Source source = socket.create_source(GLib::IOCondition::IN_, nullptr);
  49. source.set_callback<Gio::SocketSourceFunc>(receive);
  50. source.attach();
  51. }
  52. return socket;
  53. }
  54. static void
  55. die(const std::string &why)
  56. {
  57. std::cerr << why << std::endl;
  58. exit(2);
  59. }
  60. int
  61. main(int argc, char **argv)
  62. {
  63. if (argc < 2)
  64. die("missing argument");
  65. std::string msg = argv[1];
  66. std::cout << "will send message " << msg << std::endl;
  67. auto recv = open(true);
  68. auto local = gi::expect(recv.get_local_address());
  69. auto send = open(false);
  70. send.send_to(local, (guint8 *)msg.data(), msg.size(), nullptr);
  71. loop = GLib::MainLoop::new_();
  72. loop.run();
  73. }