#include "UDP.hh"
#include "../Engine.hh"
#include <ClanLib/core.h>
#include <cassert>
NetworkUDP::NetworkUDP (void) :
socket(AF_UNSPEC, SOCK_DGRAM)
{
// do not bind
// connect signal
slots.connect(socket.sig_read(), this, &NetworkUDP::on_recv);
// nonblocking
socket.set_nonblocking(true);
// activate polling
socket.set_poll_read(true);
}
NetworkUDP::NetworkUDP (const NetworkAddress &bind_addr) :
socket(AF_UNSPEC, SOCK_DGRAM) {
// bind socket
socket.bind(bind_addr);
// connect signal
slots.connect(socket.sig_read(), this, &NetworkUDP::on_recv);
// nonblocking
socket.set_nonblocking(true);
// activate polling
socket.set_poll_read(true);
}
void NetworkUDP::on_recv (void) {
size_t ret;
NetworkPacket pkt;
NetworkAddress src;
// receieve as many packets as possible
do {
// attempt to recv a packet
ret = socket.recv(pkt.get_buf(), pkt.get_buf_size(), &src);
// no more packets?
if (ret == 0)
return;
// set packet data size
pkt.set_data_size(ret);
// handle packet
_sig_packet(pkt, src);
} while (true);
}
bool NetworkUDP::sendto (const NetworkPacketBuffer &packet, const NetworkAddress &dst) {
size_t ret;
try {
// try and send
ret = socket.send(packet.get_buf(), packet.get_data_size(), &dst);
} catch (NetworkSocketError &e) {
// catch and log errors
Engine::log(WARN, "udp.sendto") << "socket->send raised error: " << e.what();
return false;
}
// weird packet size?
if (ret != packet.get_data_size()) {
Engine::log(ERROR, "udp.sendto") << "socket->send returned weird length: " << ret << ", packet was " << packet.get_data_size();
return false;
} else {
// sent
return true;
}
}