Skip to content

UDP datagrams and ping#

AUdpSocket sends and receives independent datagrams. Unlike ATcpSocket, there is no connection: every call names the peer explicitly, delivery is not guaranteed and datagrams may arrive reordered. In return, message boundaries are preserved: one write is received by exactly one read.

Receiver#

Construct the socket with a port to listen on. read blocks until a datagram arrives, fills the buffer with its payload and tells who sent it.

AUdpSocket socket(9000);
for (;;) {
    AByteBuffer buffer;
    AInet4Address sender;
    socket.read(buffer, sender);
    ALogger::info("Net") << "Got " << buffer.size() << " bytes from " << sender.toString();
}

Sender#

The default constructor picks a random port, which is what a client usually wants. write takes an AByteBufferView and the destination.

AUdpSocket socket;
auto payload = AByteBuffer::fromString("ping");
socket.write(payload, AInet4Address::fromString("127.0.0.1", 9000));

A datagram must be smaller than 32768 bytes (the sending side asserts this). If your messages are bigger, split them yourself or use TCP client and server.

Replying works the same way: pass the sender address obtained by read to write.

Pinging a host#

AIcmp::ping sends an ICMP echo request and returns an AFuture of the round trip duration. The future holds an exception if the host did not answer within the timeout (5 seconds by default).

try {
    auto rtt = *AIcmp::ping(AInet4Address::fromString("127.0.0.1"), std::chrono::seconds(1));
    ALogger::info("Net") << "Round trip: " << std::chrono::duration_cast<std::chrono::milliseconds>(rtt).count()
                         << "ms";
} catch (const AException& e) {
    ALogger::warn("Net") << "No reply: " << e;
}

See aui.network/tests/PingTest.cpp for more usages.