File: gio.cpp

package info (click to toggle)
cppgir 2.0%2Bgit20240928.c8bb1c6%2Breally2.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,228 kB
  • sloc: cpp: 14,307; ansic: 339; makefile: 11; sh: 9
file content (87 lines) | stat: -rw-r--r-- 2,132 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#define GI_INLINE 1
#include <gio/gio.hpp>

#include <iostream>

namespace GLib = gi::repository::GLib;
namespace Gio = gi::repository::Gio;

const std::string localhost("127.0.0.1");
static GLib::MainLoop loop;

// many calls here support GError
// so typically will throw here instead
// (unless GError output is explicitly requested in call signature)

static bool
receive(Gio::Socket s, GLib::IOCondition /*cond*/)
{
  guint8 buffer[1024] = {
      0,
  };
  Gio::SocketAddress a;
  int count = gi::expect(s.receive_from(&a, buffer, sizeof(buffer)));
  if (count > 0) {
    // let's see where it came from
    std::string origin("someone");
    auto ia = gi::object_cast<Gio::InetSocketAddress>(a);
    if (ia) {
      origin = ia.get_address().to_string();
      origin += ":";
      origin += std::to_string(ia.get_port());
    }
    std::cout << origin << " said " << (char *)buffer << std::endl;
    // quit when idle
    GLib::idle_add([]() {
      loop.quit();
      return GLib::SOURCE_REMOVE_;
    });
  }
  return true;
}

Gio::Socket
open(bool listen)
{
  auto socket = gi::expect(Gio::Socket::new_(Gio::SocketFamily::IPV4_,
      Gio::SocketType::DATAGRAM_, Gio::SocketProtocol::DEFAULT_));

  auto address = Gio::InetSocketAddress::new_from_string(localhost, 0);
  socket.bind(address, false);
  socket.set_blocking(false);

  if (listen) {
    // runtime introspection has a hard time here,
    // but with a bit of extra information, we can keep going
    GLib::Source source = socket.create_source(GLib::IOCondition::IN_, nullptr);
    source.set_callback<Gio::SocketSourceFunc>(receive);
    source.attach();
  }

  return socket;
}

static void
die(const std::string &why)
{
  std::cerr << why << std::endl;
  exit(2);
}

int
main(int argc, char **argv)
{
  if (argc < 2)
    die("missing argument");

  std::string msg = argv[1];
  std::cout << "will send message " << msg << std::endl;

  auto recv = open(true);
  auto local = gi::expect(recv.get_local_address());
  auto send = open(false);
  send.send_to(local, (guint8 *)msg.data(), msg.size(), nullptr);

  loop = GLib::MainLoop::new_();
  loop.run();
}