40 static unsigned char g_huffmanBuffer[131072]; |
40 static unsigned char g_huffmanBuffer[131072]; |
41 |
41 |
42 // ----------------------------------------------------------------------------- |
42 // ----------------------------------------------------------------------------- |
43 // |
43 // |
44 UDPSocket::UDPSocket() : |
44 UDPSocket::UDPSocket() : |
45 m_socket (socket (AF_INET, SOCK_DGRAM, 0)) {} |
45 m_socket (socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) {} |
46 |
46 |
47 // ----------------------------------------------------------------------------- |
47 // ----------------------------------------------------------------------------- |
48 // |
48 // |
49 UDPSocket::~UDPSocket() {} |
49 UDPSocket::~UDPSocket() {} |
50 |
50 |
52 // |
52 // |
53 METHOD |
53 METHOD |
54 UDPSocket::set_blocking (bool a) -> bool |
54 UDPSocket::set_blocking (bool a) -> bool |
55 { |
55 { |
56 int flags = fcntl (m_socket, F_GETFL, 0); |
56 int flags = fcntl (m_socket, F_GETFL, 0); |
57 int newflags = (a ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK)); |
57 int newflags = a ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK); |
58 |
58 |
59 if (flags < 0 || fcntl (m_socket, F_SETFL, newflags) != 0) |
59 if (flags < 0 || fcntl (m_socket, F_SETFL, newflags) != 0) |
60 { |
60 { |
61 m_error = "Unable to set socket as non-blocking"; |
61 m_error = "Unable to set socket as non-blocking"; |
62 return false; |
62 return false; |
90 METHOD |
90 METHOD |
91 UDPSocket::read (Datagram& datagram) -> bool |
91 UDPSocket::read (Datagram& datagram) -> bool |
92 { |
92 { |
93 sockaddr_in claddr; |
93 sockaddr_in claddr; |
94 socklen_t socklen = sizeof claddr; |
94 socklen_t socklen = sizeof claddr; |
95 static unsigned char packet[MAX_DATAGRAM_LENGTH]; |
95 int length = ::recvfrom (m_socket, g_huffmanBuffer, sizeof g_huffmanBuffer, 0, |
96 int length = ::recvfrom (m_socket, g_huffmanBuffer, sizeof packet, 0, |
|
97 reinterpret_cast<struct sockaddr*> (&claddr), &socklen); |
96 reinterpret_cast<struct sockaddr*> (&claddr), &socklen); |
98 |
97 |
99 if (length == -1) |
98 if (length == -1) |
100 { |
99 { |
101 // We got an error, though EWOULDBLOCK is silent as it means no packets recieved. |
|
102 if (errno != EWOULDBLOCK) |
100 if (errno != EWOULDBLOCK) |
103 m_error.sprintf ("recvfrom error: %s", strerror (errno));; |
101 m_error.sprintf ("recvfrom error: %s", strerror (errno)); |
104 |
102 |
105 return false; |
103 return false; |
106 } |
104 } |
107 |
105 |
108 int decodedlength = sizeof g_huffmanBuffer; |
106 unsigned char decodedPacket[MAX_DATAGRAM_LENGTH]; |
109 HUFFMAN_Decode (g_huffmanBuffer, packet, length, &decodedlength); |
107 int decodedLength = sizeof decodedPacket; |
|
108 HUFFMAN_Decode (g_huffmanBuffer, decodedPacket, length, &decodedLength); |
110 datagram.from.host = ntohl (claddr.sin_addr.s_addr); |
109 datagram.from.host = ntohl (claddr.sin_addr.s_addr); |
111 datagram.from.port = ntohs (claddr.sin_port); |
110 datagram.from.port = ntohs (claddr.sin_port); |
112 datagram.data = Bytestream (packet, decodedlength); |
111 datagram.data = Bytestream (decodedPacket, decodedLength); |
113 return true; |
112 return true; |
114 } |
113 } |
115 |
114 |
116 // ------------------------------------------------------------------------------------------------- |
115 // ------------------------------------------------------------------------------------------------- |
117 // |
116 // |
118 METHOD |
117 METHOD |
119 UDPSocket::send (const IPAddress& address, const Bytestream& data) -> bool |
118 UDPSocket::send (const IPAddress& address, const Bytestream& data) -> bool |
120 { |
119 { |
121 int encodedlength = sizeof g_huffmanBuffer; |
120 int encodedlength = sizeof g_huffmanBuffer; |
122 HUFFMAN_Encode (data.data(), g_huffmanBuffer, data.written_length(), &encodedlength); |
121 HUFFMAN_Encode (data.data(), g_huffmanBuffer, data.written_length(), &encodedlength); |
123 struct sockaddr_in claddr = address.to_sockaddr_in(); |
122 sockaddr_in claddr = address.to_sockaddr_in(); |
124 int res = ::sendto (m_socket, g_huffmanBuffer, encodedlength, 0, |
123 int res = ::sendto (m_socket, g_huffmanBuffer, encodedlength, 0, |
125 reinterpret_cast<struct sockaddr*> (&claddr), sizeof claddr); |
124 reinterpret_cast<sockaddr*> (&claddr), sizeof claddr); |
126 |
125 |
127 if (res == -1) |
126 if (res == -1) |
128 { |
127 { |
129 m_error = String ("Unable to launch packet: ") + strerror (errno); |
128 m_error = String ("Unable to launch packet: ") + strerror (errno); |
130 return false; |
129 return false; |