summaryrefslogtreecommitdiff
path: root/src/unstable/udpsocket.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/unstable/udpsocket.cpp')
-rw-r--r--src/unstable/udpsocket.cpp240
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"
13using 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
22namespace Bu { subExceptionDef( UdpSocketException ) }
23
24#define saTarget ( *((struct sockaddr_in *)paTarget) )
25
26Bu::UdpSocket::UdpSocket( int iUdpSocket ) :
27 iUdpSocket( iUdpSocket ),
28 paTarget( NULL ),
29 bBound( false )
30{
31}
32
33Bu::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
77Bu::UdpSocket::~UdpSocket()
78{
79 close();
80 delete (struct sockaddr_in *)paTarget;
81 paTarget = NULL;
82}
83
84Bu::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
93void Bu::UdpSocket::close()
94{
95 ::close( iUdpSocket );
96}
97
98Bu::size Bu::UdpSocket::read( void *pBuf, Bu::size nBytes )
99{
100 return recv( iUdpSocket, pBuf, nBytes, 0 );
101}
102
103Bu::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
115Bu::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
128Bu::size Bu::UdpSocket::tell()
129{
130 throw Bu::UnsupportedException();
131}
132
133void Bu::UdpSocket::seek( Bu::size )
134{
135 throw Bu::UnsupportedException();
136}
137
138void Bu::UdpSocket::setPos( Bu::size )
139{
140 throw Bu::UnsupportedException();
141}
142
143void Bu::UdpSocket::setPosEnd( Bu::size )
144{
145 throw Bu::UnsupportedException();
146}
147
148bool Bu::UdpSocket::isEos()
149{
150 return false;
151}
152
153bool Bu::UdpSocket::isOpen()
154{
155 return true;
156}
157
158void Bu::UdpSocket::flush()
159{
160}
161
162bool Bu::UdpSocket::canRead()
163{
164 return bBound;
165}
166
167bool Bu::UdpSocket::canWrite()
168{
169 return true;
170}
171
172bool Bu::UdpSocket::isReadable()
173{
174 return bBound;
175}
176
177bool Bu::UdpSocket::isWritable()
178{
179 return true;
180}
181
182bool Bu::UdpSocket::isSeekable()
183{
184 return false;
185}
186
187bool Bu::UdpSocket::isBlocking()
188{
189 return true;
190}
191
192void 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
219void Bu::UdpSocket::setSize( Bu::size )
220{
221 throw Bu::UnsupportedException();
222}
223
224Bu::size Bu::UdpSocket::getSize() const
225{
226 throw Bu::UnsupportedException();
227}
228
229Bu::size Bu::UdpSocket::getBlockSize() const
230{
231 return 1500;
232}
233
234Bu::String Bu::UdpSocket::getLocation() const
235{
236 throw Bu::UnsupportedException();
237}
238
239#endif
240