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