3 #include <sys/time.h> |
3 #include <sys/time.h> |
4 #include <netinet/in.h> |
4 #include <netinet/in.h> |
5 #include <string.h> |
5 #include <string.h> |
6 #include <fcntl.h> |
6 #include <fcntl.h> |
7 #include "udpsocket.h" |
7 #include "udpsocket.h" |
|
8 #include "../huffman/huffman.h" |
|
9 |
|
10 static unsigned char g_huffmanBuffer[131072]; |
8 |
11 |
9 // ----------------------------------------------------------------------------- |
12 // ----------------------------------------------------------------------------- |
10 // |
13 // |
11 UDPSocket::UDPSocket() : |
14 UDPSocket::UDPSocket() : |
12 m_socket (socket (AF_INET, SOCK_DGRAM, 0)) {} |
15 m_socket (socket (AF_INET, SOCK_DGRAM, 0)) {} |
19 // |
22 // |
20 METHOD |
23 METHOD |
21 UDPSocket::set_blocking (bool a) -> bool |
24 UDPSocket::set_blocking (bool a) -> bool |
22 { |
25 { |
23 int flags = fcntl (m_socket, F_GETFL, 0); |
26 int flags = fcntl (m_socket, F_GETFL, 0); |
24 int newflags = (a ? (flags | O_NONBLOCK) : (flags & ~O_NONBLOCK)); |
27 int newflags = (a ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK)); |
25 |
28 |
26 if (flags < 0 || fcntl (m_socket, F_SETFL, newflags) != 0) |
29 if (flags < 0 || fcntl (m_socket, F_SETFL, newflags) != 0) |
27 { |
30 { |
28 m_error = "Unable to set socket as non-blocking"; |
31 m_error = "Unable to set socket as non-blocking"; |
29 return false; |
32 return false; |
58 UDPSocket::read (Datagram& datagram) -> bool |
61 UDPSocket::read (Datagram& datagram) -> bool |
59 { |
62 { |
60 sockaddr_in claddr; |
63 sockaddr_in claddr; |
61 socklen_t socklen = sizeof claddr; |
64 socklen_t socklen = sizeof claddr; |
62 static unsigned char packet[MAX_DATAGRAM_LENGTH]; |
65 static unsigned char packet[MAX_DATAGRAM_LENGTH]; |
63 int length = ::recvfrom (m_socket, packet, sizeof packet, 0, |
66 int length = ::recvfrom (m_socket, g_huffmanBuffer, sizeof packet, 0, |
64 reinterpret_cast<struct sockaddr*> (&claddr), &socklen); |
67 reinterpret_cast<struct sockaddr*> (&claddr), &socklen); |
65 |
68 |
66 if (length == -1) |
69 if (length == -1) |
67 { |
70 { |
68 // We got an error, though EWOULDBLOCK is silent as it means no packets recieved. |
71 // We got an error, though EWOULDBLOCK is silent as it means no packets recieved. |
70 m_error.sprintf ("recvfrom error: %s", strerror (errno));; |
73 m_error.sprintf ("recvfrom error: %s", strerror (errno));; |
71 |
74 |
72 return false; |
75 return false; |
73 } |
76 } |
74 |
77 |
|
78 int decodedlength = sizeof g_huffmanBuffer; |
|
79 HUFFMAN_Decode (g_huffmanBuffer, packet, length, &decodedlength); |
75 datagram.from.host = ntohl (claddr.sin_addr.s_addr); |
80 datagram.from.host = ntohl (claddr.sin_addr.s_addr); |
76 datagram.from.port = ntohs (claddr.sin_port); |
81 datagram.from.port = ntohs (claddr.sin_port); |
77 datagram.data = Bytestream (packet, length); |
82 datagram.data = Bytestream (packet, decodedlength); |
78 return true; |
83 return true; |
79 } |
84 } |
80 |
85 |
81 // ------------------------------------------------------------------------------------------------- |
86 // ------------------------------------------------------------------------------------------------- |
82 // |
87 // |
83 METHOD |
88 METHOD |
84 UDPSocket::send (const Bytestream& data, const IPAddress& addr) -> bool |
89 UDPSocket::send (const IPAddress& address, const Bytestream& data) -> bool |
85 { |
90 { |
86 struct sockaddr_in claddr = addr.to_sockaddr_in(); |
91 int encodedlength = sizeof g_huffmanBuffer; |
87 |
92 HUFFMAN_Encode (data.data(), g_huffmanBuffer, data.written_length(), &encodedlength); |
88 int res = ::sendto (m_socket, data.data(), data.written_length(), 0, |
93 struct sockaddr_in claddr = address.to_sockaddr_in(); |
|
94 int res = ::sendto (m_socket, g_huffmanBuffer, encodedlength, 0, |
89 reinterpret_cast<struct sockaddr*> (&claddr), sizeof claddr); |
95 reinterpret_cast<struct sockaddr*> (&claddr), sizeof claddr); |
90 |
96 |
91 if (res == -1) |
97 if (res == -1) |
92 { |
98 { |
93 m_error = String ("Unable to launch packet: ") + strerror (errno); |
99 m_error = String ("Unable to launch packet: ") + strerror (errno); |