26 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
26 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
27 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
27 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
28 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
28 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 */ |
29 */ |
30 |
30 |
31 #include <sys/socket.h> |
31 #include "udpsocket.h" |
|
32 |
|
33 #ifndef _WIN32 |
|
34 # include <sys/socket.h> |
|
35 # include <netinet/in.h> |
|
36 #else |
|
37 # include <winsock2.h> |
|
38 # include <ws2tcpip.h> |
|
39 #endif |
|
40 |
32 #include <sys/types.h> |
41 #include <sys/types.h> |
33 #include <sys/time.h> |
42 #include <sys/time.h> |
34 #include <netinet/in.h> |
|
35 #include <string.h> |
43 #include <string.h> |
36 #include <fcntl.h> |
44 #include <fcntl.h> |
37 #include <unistd.h> |
45 #include <unistd.h> |
38 #include "udpsocket.h" |
|
39 #include "../huffman/huffman.h" |
46 #include "../huffman/huffman.h" |
40 |
47 |
41 static unsigned char g_huffmanBuffer[131072]; |
48 static char g_huffmanBuffer[131072]; |
42 |
49 |
43 // ----------------------------------------------------------------------------- |
50 // ----------------------------------------------------------------------------- |
44 // |
51 // |
45 UDPSocket::UDPSocket() : |
52 UDPSocket::UDPSocket() : |
46 m_socket (socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) {} |
53 m_socket (socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) {} |
52 close (m_socket); |
59 close (m_socket); |
53 } |
60 } |
54 |
61 |
55 // ------------------------------------------------------------------------------------------------- |
62 // ------------------------------------------------------------------------------------------------- |
56 // |
63 // |
57 METHOD |
64 bool UDPSocket::set_blocking (bool a) |
58 UDPSocket::set_blocking (bool a) -> bool |
|
59 { |
65 { |
|
66 #ifndef _WIN32 |
60 int flags = fcntl (m_socket, F_GETFL, 0); |
67 int flags = fcntl (m_socket, F_GETFL, 0); |
61 int newflags = a ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK); |
68 int newflags = a ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK); |
62 |
69 |
63 if (flags < 0 || fcntl (m_socket, F_SETFL, newflags) != 0) |
70 if (flags < 0 || fcntl (m_socket, F_SETFL, newflags) != 0) |
64 { |
71 { |
65 m_error = "Unable to set socket as non-blocking"; |
72 m_error = "Unable to set socket as non-blocking"; |
66 return false; |
73 return false; |
67 } |
74 } |
68 |
75 |
69 return true; |
76 return true; |
|
77 #else |
|
78 unsigned long mode = a ? 0 : 1; |
|
79 |
|
80 if (ioctlsocket (m_socket, FIONBIO, &mode) != 0) |
|
81 { |
|
82 m_error = strerror (errno); |
|
83 return false; |
|
84 } |
|
85 |
|
86 return true; |
|
87 #endif |
70 } |
88 } |
71 |
89 |
72 // ------------------------------------------------------------------------------------------------- |
90 // ------------------------------------------------------------------------------------------------- |
73 // |
91 // |
74 METHOD |
92 METHOD |
89 return true; |
107 return true; |
90 } |
108 } |
91 |
109 |
92 // ------------------------------------------------------------------------------------------------- |
110 // ------------------------------------------------------------------------------------------------- |
93 // |
111 // |
94 METHOD |
112 bool UDPSocket::read (Datagram& datagram) |
95 UDPSocket::read (Datagram& datagram) -> bool |
|
96 { |
113 { |
97 sockaddr_in claddr; |
114 sockaddr_in claddr; |
98 socklen_t socklen = sizeof claddr; |
115 socklen_t socklen = sizeof claddr; |
99 int length = ::recvfrom (m_socket, g_huffmanBuffer, sizeof g_huffmanBuffer, 0, |
116 int length = ::recvfrom (m_socket, g_huffmanBuffer, sizeof g_huffmanBuffer, 0, |
100 reinterpret_cast<sockaddr*> (&claddr), &socklen); |
117 reinterpret_cast<sockaddr*> (&claddr), &socklen); |
107 return false; |
124 return false; |
108 } |
125 } |
109 |
126 |
110 unsigned char decodedPacket[MAX_DATAGRAM_LENGTH]; |
127 unsigned char decodedPacket[MAX_DATAGRAM_LENGTH]; |
111 int decodedLength = sizeof decodedPacket; |
128 int decodedLength = sizeof decodedPacket; |
112 HUFFMAN_Decode (g_huffmanBuffer, decodedPacket, length, &decodedLength); |
129 HUFFMAN_Decode (reinterpret_cast<unsigned char*> (g_huffmanBuffer), |
|
130 decodedPacket, length, &decodedLength); |
113 datagram.from.host = ntohl (claddr.sin_addr.s_addr); |
131 datagram.from.host = ntohl (claddr.sin_addr.s_addr); |
114 datagram.from.port = ntohs (claddr.sin_port); |
132 datagram.from.port = ntohs (claddr.sin_port); |
115 datagram.data = Bytestream (decodedPacket, decodedLength); |
133 datagram.data = Bytestream (decodedPacket, decodedLength); |
116 return true; |
134 return true; |
117 } |
135 } |
120 // |
138 // |
121 METHOD |
139 METHOD |
122 UDPSocket::send (const IPAddress& address, const Bytestream& data) -> bool |
140 UDPSocket::send (const IPAddress& address, const Bytestream& data) -> bool |
123 { |
141 { |
124 int encodedlength = sizeof g_huffmanBuffer; |
142 int encodedlength = sizeof g_huffmanBuffer; |
125 HUFFMAN_Encode (data.data(), g_huffmanBuffer, data.written_length(), &encodedlength); |
143 HUFFMAN_Encode (data.data(), reinterpret_cast<unsigned char*> (g_huffmanBuffer), |
|
144 data.written_length(), &encodedlength); |
126 sockaddr_in claddr = address.to_sockaddr_in(); |
145 sockaddr_in claddr = address.to_sockaddr_in(); |
127 int res = ::sendto (m_socket, g_huffmanBuffer, encodedlength, 0, |
146 int res = ::sendto (m_socket, g_huffmanBuffer, encodedlength, 0, |
128 reinterpret_cast<sockaddr*> (&claddr), sizeof claddr); |
147 reinterpret_cast<sockaddr*> (&claddr), sizeof claddr); |
129 |
148 |
130 if (res == -1) |
149 if (res == -1) |