src/Network/UDP.cc
author terom
Wed, 03 Dec 2008 19:30:54 +0000
changeset 186 0738f2949a2b
parent 185 src/NetworkUDP.cc@25becd2cb026
child 202 b3f5d766391e
permissions -rw-r--r--
move src/Network% to src/Network/%

#include "UDP.hh"

#include <ClanLib/core.h>
#include <cassert>

NetworkUDP::NetworkUDP (void) : 
    socket(CL_Socket::udp, CL_Socket::ipv4) {
    
    // do not bind

    // connect signal
    slots.connect(socket.sig_read_triggered(), this, &NetworkUDP::on_recv);

    // nonblocking
    socket.set_nonblocking(true);
}

NetworkUDP::NetworkUDP (const NetworkAddress &bind_addr) :
    socket(CL_Socket::udp, CL_Socket::ipv4) {
    
    // bind socket
    socket.bind(bind_addr);

    // connect signal
    slots.connect(socket.sig_read_triggered(), this, &NetworkUDP::on_recv);

    // nonblocking
    socket.set_nonblocking(true);
}
        
void NetworkUDP::on_recv (void) {
    int ret;
    NetworkPacket pkt;
    NetworkAddress src;
    
    // receieve as many packets as possible
    do {    
        // attempt to recv a packet
        try {
            ret = socket.recv(pkt.get_buf(), pkt.get_buf_size(), src);

        } catch (CL_Error &e) {
            if (errno == EAGAIN)
                return;
            else
                throw;
        }
        
        // set packet data size
        pkt.set_data_size(ret);

        // handle packet
        _sig_packet(pkt, src);

    } while (true);
}
        
bool NetworkUDP::sendto (const NetworkPacket &packet, const NetworkAddress &dst) {
    int ret;

    // XXX: shouldn't get trimmed
    try {
        ret = socket.send(packet.get_buf(), packet.get_data_size(), dst);

    } catch (CL_Error &e) {
        // XXX: catch some errors, but not others?
        return false;
    }

    assert(ret > 0);
    
    // UDP shouldn't trim packets
    assert((unsigned int) ret == packet.get_data_size());
    
    // good
    return true;
}