src/Network/UDP.cc
changeset 378 5589abf5e61b
parent 202 b3f5d766391e
child 380 d193dd1d8a7e
equal deleted inserted replaced
377:01d3c340b372 378:5589abf5e61b
     1 
     1 
     2 #include "UDP.hh"
     2 #include "UDP.hh"
       
     3 #include "../Engine.hh"
     3 
     4 
     4 #include <ClanLib/core.h>
     5 #include <ClanLib/core.h>
     5 #include <cassert>
     6 #include <cassert>
     6 
     7 
     7 NetworkUDP::NetworkUDP (void) : 
     8 NetworkUDP::NetworkUDP (void) : 
     8     socket(CL_Socket::udp, CL_Socket::ipv4) {
     9     socket(AF_UNSPEC, SOCK_DGRAM) 
     9     
    10 {
    10     // do not bind
    11     // do not bind
    11 
    12 
    12     // connect signal
    13     // connect signal
    13     slots.connect(socket.sig_read_triggered(), this, &NetworkUDP::on_recv);
    14     slots.connect(socket.sig_read(), this, &NetworkUDP::on_recv);
    14 
    15 
    15     // nonblocking
    16     // nonblocking
    16     socket.set_nonblocking(true);
    17     socket.set_nonblocking(true);
    17 }
    18 }
    18 
    19 
    19 NetworkUDP::NetworkUDP (const NetworkAddress &bind_addr) :
    20 NetworkUDP::NetworkUDP (const NetworkAddress &bind_addr) :
    20     socket(CL_Socket::udp, CL_Socket::ipv4) {
    21     socket(AF_UNSPEC, SOCK_DGRAM) {
    21     
    22     
    22     // bind socket
    23     // bind socket
    23     socket.bind(bind_addr);
    24     socket.bind(bind_addr);
    24 
    25 
    25     // connect signal
    26     // connect signal
    26     slots.connect(socket.sig_read_triggered(), this, &NetworkUDP::on_recv);
    27     slots.connect(socket.sig_read(), this, &NetworkUDP::on_recv);
    27 
    28 
    28     // nonblocking
    29     // nonblocking
    29     socket.set_nonblocking(true);
    30     socket.set_nonblocking(true);
    30 }
    31 }
    31         
    32         
    32 void NetworkUDP::on_recv (void) {
    33 void NetworkUDP::on_recv (void) {
    33     int ret;
    34     size_t ret;
    34     NetworkPacket pkt;
    35     NetworkPacket pkt;
    35     NetworkAddress src;
    36     NetworkAddress src;
    36     
    37     
    37     // receieve as many packets as possible
    38     // receieve as many packets as possible
    38     do {    
    39     do {    
    39         // attempt to recv a packet
    40         // attempt to recv a packet
    40         try {
    41         ret = socket.recv(pkt.get_buf(), pkt.get_buf_size(), &src);
    41             ret = socket.recv(pkt.get_buf(), pkt.get_buf_size(), src);
    42         
       
    43         // no more packets?
       
    44         if (ret == 0)
       
    45             return;
    42 
    46 
    43         } catch (CL_Error &e) {
       
    44             if (errno == EAGAIN)
       
    45                 return;
       
    46             else
       
    47                 throw;
       
    48         }
       
    49         
       
    50         // set packet data size
    47         // set packet data size
    51         pkt.set_data_size(ret);
    48         pkt.set_data_size(ret);
    52 
    49 
    53         // handle packet
    50         // handle packet
    54         _sig_packet(pkt, src);
    51         _sig_packet(pkt, src);
    55 
    52 
    56     } while (true);
    53     } while (true);
    57 }
    54 }
    58         
    55         
    59 bool NetworkUDP::sendto (const NetworkPacketBuffer &packet, const NetworkAddress &dst) {
    56 bool NetworkUDP::sendto (const NetworkPacketBuffer &packet, const NetworkAddress &dst) {
    60     int ret;
    57     size_t ret;
    61 
    58 
    62     // XXX: shouldn't get trimmed
       
    63     try {
    59     try {
    64         ret = socket.send(packet.get_buf(), packet.get_data_size(), dst);
    60         // try and send
       
    61         ret = socket.send(packet.get_buf(), packet.get_data_size(), &dst);
    65 
    62 
    66     } catch (CL_Error &e) {
    63     } catch (NetworkSocketError &e) {
    67         // XXX: catch some errors, but not others?
    64         // catch and log errors
       
    65         Engine::log(WARN, "udp.sendto") << "socket->send raised error: " << e.what();
    68         return false;
    66         return false;
    69     }
    67     }
       
    68     
       
    69     // weird packet size?
       
    70     if (ret != packet.get_data_size()) {
       
    71         Engine::log(ERROR, "udp.sendto") << "socket->send returned weird length: " << ret << ", packet was " << packet.get_data_size();
       
    72         return false;
    70 
    73 
    71     assert(ret > 0);
    74     } else {
    72     
    75         // sent
    73     // UDP shouldn't trim packets
    76         return true;
    74     assert((unsigned int) ret == packet.get_data_size());
    77     }
    75     
       
    76     // good
       
    77     return true;
       
    78 }
    78 }
    79 
    79