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