diff options
author | Mike Buland <eichlan@xagasoft.com> | 2012-03-25 20:00:08 +0000 |
---|---|---|
committer | Mike Buland <eichlan@xagasoft.com> | 2012-03-25 20:00:08 +0000 |
commit | 469bbcf0701e1eb8a6670c23145b0da87357e178 (patch) | |
tree | b5b062a16e46a6c5d3410b4e574cd0cc09057211 /src/unstable/udpsocket.cpp | |
parent | ee1b79396076edc4e30aefb285fada03bb45e80d (diff) | |
download | libbu++-469bbcf0701e1eb8a6670c23145b0da87357e178.tar.gz libbu++-469bbcf0701e1eb8a6670c23145b0da87357e178.tar.bz2 libbu++-469bbcf0701e1eb8a6670c23145b0da87357e178.tar.xz libbu++-469bbcf0701e1eb8a6670c23145b0da87357e178.zip |
Code is all reorganized. We're about ready to release. I should write up a
little explenation of the arrangement.
Diffstat (limited to 'src/unstable/udpsocket.cpp')
-rw-r--r-- | src/unstable/udpsocket.cpp | 240 |
1 files changed, 240 insertions, 0 deletions
diff --git a/src/unstable/udpsocket.cpp b/src/unstable/udpsocket.cpp new file mode 100644 index 0000000..702840a --- /dev/null +++ b/src/unstable/udpsocket.cpp | |||
@@ -0,0 +1,240 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007-2011 Xagasoft, All rights reserved. | ||
3 | * | ||
4 | * This file is part of the libbu++ library and is released under the | ||
5 | * terms of the license contained in the file LICENSE. | ||
6 | */ | ||
7 | |||
8 | #ifndef WIN32 //not on windows | ||
9 | |||
10 | #include "bu/udpsocket.h" | ||
11 | |||
12 | #include "bu/sio.h" | ||
13 | using namespace Bu; | ||
14 | #include <fcntl.h> | ||
15 | |||
16 | #include <errno.h> | ||
17 | #include <arpa/inet.h> | ||
18 | #include <sys/socket.h> | ||
19 | #include <netinet/in.h> | ||
20 | #include <sys/utsname.h> | ||
21 | |||
22 | namespace Bu { subExceptionDef( UdpSocketException ) } | ||
23 | |||
24 | #define saTarget ( *((struct sockaddr_in *)paTarget) ) | ||
25 | |||
26 | Bu::UdpSocket::UdpSocket( int iUdpSocket ) : | ||
27 | iUdpSocket( iUdpSocket ), | ||
28 | paTarget( NULL ), | ||
29 | bBound( false ) | ||
30 | { | ||
31 | } | ||
32 | |||
33 | Bu::UdpSocket::UdpSocket( const Bu::String &sAddr, int iPort, int iFlags ) : | ||
34 | iUdpSocket( 0 ), | ||
35 | paTarget( NULL ), | ||
36 | bBound( false ) | ||
37 | { | ||
38 | iUdpSocket = socket( PF_INET, SOCK_DGRAM, 0 ); | ||
39 | if( iUdpSocket < 0 ) | ||
40 | { | ||
41 | throw UdpSocketException("Couldn't open udp socket: %s", | ||
42 | strerror( errno ) | ||
43 | ); | ||
44 | } | ||
45 | |||
46 | if( (iFlags&Broadcast) ) | ||
47 | { | ||
48 | int broadcast = 1; | ||
49 | if( (setsockopt( iUdpSocket, SOL_SOCKET, SO_BROADCAST, | ||
50 | &broadcast, sizeof(broadcast) )) == -1) | ||
51 | { | ||
52 | throw UdpSocketException("Couldn't set udp socket to broadcast: %s", | ||
53 | strerror( errno ) | ||
54 | ); | ||
55 | } | ||
56 | } | ||
57 | |||
58 | paTarget = new struct sockaddr_in; | ||
59 | saTarget.sin_family = AF_INET; | ||
60 | saTarget.sin_port = htons( iPort ); | ||
61 | saTarget.sin_addr.s_addr = inet_addr( sAddr.getStr() ); // INADDR_ANY; | ||
62 | memset( saTarget.sin_zero, '\0', sizeof(saTarget.sin_zero) ); | ||
63 | |||
64 | if( (iFlags&Read) ) | ||
65 | { | ||
66 | if( bind( iUdpSocket, (struct sockaddr*)paTarget, sizeof(struct sockaddr_in) ) | ||
67 | == -1 ) | ||
68 | { | ||
69 | throw UdpSocketException("Couldn't bind port to udp socket: %s", | ||
70 | strerror( errno ) | ||
71 | ); | ||
72 | } | ||
73 | bBound = true; | ||
74 | } | ||
75 | } | ||
76 | |||
77 | Bu::UdpSocket::~UdpSocket() | ||
78 | { | ||
79 | close(); | ||
80 | delete (struct sockaddr_in *)paTarget; | ||
81 | paTarget = NULL; | ||
82 | } | ||
83 | |||
84 | Bu::String Bu::UdpSocket::addrToStr( const addr &a ) | ||
85 | { | ||
86 | return Bu::String("%1.%2.%3.%4"). | ||
87 | arg( (a&0xff) ). | ||
88 | arg( (a&0xff00)>>8 ). | ||
89 | arg( (a&0xff0000)>>16 ). | ||
90 | arg( (a&0xff000000)>>24 ); | ||
91 | } | ||
92 | |||
93 | void Bu::UdpSocket::close() | ||
94 | { | ||
95 | ::close( iUdpSocket ); | ||
96 | } | ||
97 | |||
98 | Bu::size Bu::UdpSocket::read( void *pBuf, Bu::size nBytes ) | ||
99 | { | ||
100 | return recv( iUdpSocket, pBuf, nBytes, 0 ); | ||
101 | } | ||
102 | |||
103 | Bu::size Bu::UdpSocket::read( void *pBuf, Bu::size nBytes, | ||
104 | Bu::UdpSocket::addr &aHost, int &iPort ) | ||
105 | { | ||
106 | sockaddr_in name; | ||
107 | socklen_t size = sizeof(name); | ||
108 | Bu::size ret = recvfrom( iUdpSocket, pBuf, nBytes, 0, | ||
109 | (struct sockaddr *)&name, &size ); | ||
110 | aHost = name.sin_addr.s_addr; | ||
111 | iPort = ntohs(name.sin_port); | ||
112 | return ret; | ||
113 | } | ||
114 | |||
115 | Bu::size Bu::UdpSocket::write( const void *pBuf, Bu::size nBytes ) | ||
116 | { | ||
117 | if( bBound ) | ||
118 | { | ||
119 | return sendto( iUdpSocket, pBuf, nBytes, 0, NULL, 0 ); | ||
120 | } | ||
121 | else | ||
122 | { | ||
123 | return sendto( iUdpSocket, pBuf, nBytes, 0, | ||
124 | (struct sockaddr*)paTarget, sizeof(struct sockaddr_in) ); | ||
125 | } | ||
126 | } | ||
127 | |||
128 | Bu::size Bu::UdpSocket::tell() | ||
129 | { | ||
130 | throw Bu::UnsupportedException(); | ||
131 | } | ||
132 | |||
133 | void Bu::UdpSocket::seek( Bu::size ) | ||
134 | { | ||
135 | throw Bu::UnsupportedException(); | ||
136 | } | ||
137 | |||
138 | void Bu::UdpSocket::setPos( Bu::size ) | ||
139 | { | ||
140 | throw Bu::UnsupportedException(); | ||
141 | } | ||
142 | |||
143 | void Bu::UdpSocket::setPosEnd( Bu::size ) | ||
144 | { | ||
145 | throw Bu::UnsupportedException(); | ||
146 | } | ||
147 | |||
148 | bool Bu::UdpSocket::isEos() | ||
149 | { | ||
150 | return false; | ||
151 | } | ||
152 | |||
153 | bool Bu::UdpSocket::isOpen() | ||
154 | { | ||
155 | return true; | ||
156 | } | ||
157 | |||
158 | void Bu::UdpSocket::flush() | ||
159 | { | ||
160 | } | ||
161 | |||
162 | bool Bu::UdpSocket::canRead() | ||
163 | { | ||
164 | return bBound; | ||
165 | } | ||
166 | |||
167 | bool Bu::UdpSocket::canWrite() | ||
168 | { | ||
169 | return true; | ||
170 | } | ||
171 | |||
172 | bool Bu::UdpSocket::isReadable() | ||
173 | { | ||
174 | return bBound; | ||
175 | } | ||
176 | |||
177 | bool Bu::UdpSocket::isWritable() | ||
178 | { | ||
179 | return true; | ||
180 | } | ||
181 | |||
182 | bool Bu::UdpSocket::isSeekable() | ||
183 | { | ||
184 | return false; | ||
185 | } | ||
186 | |||
187 | bool Bu::UdpSocket::isBlocking() | ||
188 | { | ||
189 | return true; | ||
190 | } | ||
191 | |||
192 | void Bu::UdpSocket::setBlocking( bool bBlocking ) | ||
193 | { | ||
194 | #ifndef WIN32 | ||
195 | if( bBlocking ) | ||
196 | { | ||
197 | fcntl( iUdpSocket, F_SETFL, fcntl( iUdpSocket, F_GETFL, 0 ) & (~O_NONBLOCK) ); | ||
198 | } | ||
199 | else | ||
200 | { | ||
201 | fcntl( iUdpSocket, F_SETFL, fcntl( iUdpSocket, F_GETFL, 0 ) | O_NONBLOCK ); | ||
202 | } | ||
203 | #else | ||
204 | u_long iMode; | ||
205 | if( bBlocking ) | ||
206 | iMode = 0; | ||
207 | else | ||
208 | iMode = 1; | ||
209 | //------------------------- | ||
210 | // Set the socket I/O mode: In this case FIONBIO | ||
211 | // enables or disables the blocking mode for the | ||
212 | // socket based on the numerical value of iMode. | ||
213 | // If iMode = 0, blocking is enabled; | ||
214 | // If iMode != 0, non-blocking mode is enabled. | ||
215 | bu_ioctlsocket(iUdpSocket, FIONBIO, &iMode); | ||
216 | #endif | ||
217 | } | ||
218 | |||
219 | void Bu::UdpSocket::setSize( Bu::size ) | ||
220 | { | ||
221 | throw Bu::UnsupportedException(); | ||
222 | } | ||
223 | |||
224 | Bu::size Bu::UdpSocket::getSize() const | ||
225 | { | ||
226 | throw Bu::UnsupportedException(); | ||
227 | } | ||
228 | |||
229 | Bu::size Bu::UdpSocket::getBlockSize() const | ||
230 | { | ||
231 | return 1500; | ||
232 | } | ||
233 | |||
234 | Bu::String Bu::UdpSocket::getLocation() const | ||
235 | { | ||
236 | throw Bu::UnsupportedException(); | ||
237 | } | ||
238 | |||
239 | #endif | ||
240 | |||