diff options
Diffstat (limited to '')
-rw-r--r-- | src/tests/udpsocket.cpp | 41 | ||||
-rw-r--r-- | src/udpsocket.cpp | 79 | ||||
-rw-r--r-- | src/udpsocket.h | 13 |
3 files changed, 91 insertions, 42 deletions
diff --git a/src/tests/udpsocket.cpp b/src/tests/udpsocket.cpp new file mode 100644 index 0000000..63aa576 --- /dev/null +++ b/src/tests/udpsocket.cpp | |||
@@ -0,0 +1,41 @@ | |||
1 | #include "bu/udpsocket.h" | ||
2 | #include "bu/sio.h" | ||
3 | |||
4 | using namespace Bu; | ||
5 | |||
6 | int main( int argc, char *argv[] ) | ||
7 | { | ||
8 | if( argv[1][0] == 'l' ) | ||
9 | { | ||
10 | sio << "Listening..." << sio.nl; | ||
11 | Bu::UdpSocket udp( "255.255.255.255", 6688, UdpSocket::Read|UdpSocket::Broadcast ); | ||
12 | |||
13 | for(;;) | ||
14 | { | ||
15 | char buf[1501]; | ||
16 | int iRead = udp.read( buf, 1500 ); | ||
17 | buf[iRead] = '\0'; | ||
18 | sio << "Read(" << iRead << "): '" << buf << "'"; | ||
19 | } | ||
20 | } | ||
21 | else if( argv[1][0] == 'b' ) | ||
22 | { | ||
23 | sio << "Broadcasting..." << sio.nl; | ||
24 | Bu::UdpSocket udp("255.255.255.255", 6688, | ||
25 | UdpSocket::Write|UdpSocket::Broadcast ); | ||
26 | |||
27 | for(;;) | ||
28 | { | ||
29 | udp.write("hello", 5 ); | ||
30 | usleep( 250000 ); | ||
31 | } | ||
32 | } | ||
33 | else | ||
34 | { | ||
35 | sio << "Options are 'l' for listening and 'b' for broadcasting." | ||
36 | << sio.nl; | ||
37 | } | ||
38 | |||
39 | return 0; | ||
40 | } | ||
41 | |||
diff --git a/src/udpsocket.cpp b/src/udpsocket.cpp index d836690..7b03b78 100644 --- a/src/udpsocket.cpp +++ b/src/udpsocket.cpp | |||
@@ -8,17 +8,20 @@ | |||
8 | 8 | ||
9 | namespace Bu { subExceptionDef( UdpSocketException ) } | 9 | namespace Bu { subExceptionDef( UdpSocketException ) } |
10 | 10 | ||
11 | #define saTarget ( *((struct sockaddr_in *)paTarget) ) | ||
12 | |||
11 | Bu::UdpSocket::UdpSocket( int iUdpSocket ) : | 13 | Bu::UdpSocket::UdpSocket( int iUdpSocket ) : |
12 | iUdpSocket( iUdpSocket ) | 14 | iUdpSocket( iUdpSocket ), |
15 | paTarget( NULL ), | ||
16 | bBound( false ) | ||
13 | { | 17 | { |
14 | } | 18 | } |
15 | 19 | ||
16 | Bu::UdpSocket::UdpSocket( const Bu::FString &sAddr, int iPort, | 20 | Bu::UdpSocket::UdpSocket( const Bu::FString &sAddr, int iPort, int iFlags ) : |
17 | bool bBroadcast ) : | 21 | iUdpSocket( 0 ), |
18 | iUdpSocket( 0 ) | 22 | paTarget( NULL ), |
23 | bBound( false ) | ||
19 | { | 24 | { |
20 | struct sockaddr_in name; | ||
21 | |||
22 | iUdpSocket = socket( PF_INET, SOCK_DGRAM, 0 ); | 25 | iUdpSocket = socket( PF_INET, SOCK_DGRAM, 0 ); |
23 | if( iUdpSocket < 0 ) | 26 | if( iUdpSocket < 0 ) |
24 | { | 27 | { |
@@ -27,7 +30,7 @@ Bu::UdpSocket::UdpSocket( const Bu::FString &sAddr, int iPort, | |||
27 | ); | 30 | ); |
28 | } | 31 | } |
29 | 32 | ||
30 | if( bBroadcast ) | 33 | if( (iFlags&Broadcast) ) |
31 | { | 34 | { |
32 | int broadcast = 1; | 35 | int broadcast = 1; |
33 | if( (setsockopt( iUdpSocket, SOL_SOCKET, SO_BROADCAST, | 36 | if( (setsockopt( iUdpSocket, SOL_SOCKET, SO_BROADCAST, |
@@ -39,42 +42,29 @@ Bu::UdpSocket::UdpSocket( const Bu::FString &sAddr, int iPort, | |||
39 | } | 42 | } |
40 | } | 43 | } |
41 | 44 | ||
42 | name.sin_family = AF_INET; | 45 | paTarget = new struct sockaddr_in; |
43 | name.sin_port = htons( iPort ); | 46 | saTarget.sin_family = AF_INET; |
44 | name.sin_addr.s_addr = INADDR_ANY; | 47 | saTarget.sin_port = htons( iPort ); |
45 | memset( name.sin_zero, '\0', sizeof(name.sin_zero) ); | 48 | saTarget.sin_addr.s_addr = inet_addr( sAddr.getStr() ); // INADDR_ANY; |
46 | 49 | memset( saTarget.sin_zero, '\0', sizeof(saTarget.sin_zero) ); | |
47 | if( bind( iUdpSocket, (struct sockaddr*) &name, sizeof(name) ) == -1 ) | ||
48 | { | ||
49 | throw UdpSocketException("Couldn't bind port to udp socket: %s", | ||
50 | strerror( errno ) | ||
51 | ); | ||
52 | } | ||
53 | 50 | ||
54 | name.sin_family = AF_INET; | 51 | if( (iFlags&Read) ) |
55 | name.sin_port = htons( iPort ); | ||
56 | name.sin_addr.s_addr = inet_addr( sAddr.getStr() ); | ||
57 | memset( name.sin_zero, '\0', sizeof(name.sin_zero) ); | ||
58 | /* | ||
59 | while( true ) | ||
60 | { | 52 | { |
61 | nbytes = sendto( iUdpSocket, "12345", 5, 0, | 53 | if( bind( iUdpSocket, (struct sockaddr*)paTarget, sizeof(struct sockaddr_in) ) |
62 | (struct sockaddr *)&name, size ); | 54 | == -1 ) |
63 | if( nbytes < 0 ) | ||
64 | { | ||
65 | perror("sendto"); | ||
66 | // exit( 0 ); | ||
67 | } | ||
68 | |||
69 | printf("Client wrote something\n"); | ||
70 | int nQueen = sockServe.accept( 3, 0 ); | ||
71 | if( nQueen >= 0 ) | ||
72 | { | 55 | { |
73 | close( iUdpSocket ); | 56 | throw UdpSocketException("Couldn't bind port to udp socket: %s", |
74 | return nQueen; | 57 | strerror( errno ) |
58 | ); | ||
75 | } | 59 | } |
60 | bBound = true; | ||
76 | } | 61 | } |
77 | */ | 62 | } |
63 | |||
64 | Bu::UdpSocket::~UdpSocket() | ||
65 | { | ||
66 | delete (struct sockaddr_in *)paTarget; | ||
67 | paTarget = NULL; | ||
78 | } | 68 | } |
79 | 69 | ||
80 | void Bu::UdpSocket::close() | 70 | void Bu::UdpSocket::close() |
@@ -84,6 +74,7 @@ void Bu::UdpSocket::close() | |||
84 | 74 | ||
85 | size_t Bu::UdpSocket::read( void *pBuf, size_t nBytes ) | 75 | size_t Bu::UdpSocket::read( void *pBuf, size_t nBytes ) |
86 | { | 76 | { |
77 | return recvfrom( iUdpSocket, pBuf, nBytes, 0, NULL, 0 ); | ||
87 | } | 78 | } |
88 | 79 | ||
89 | size_t Bu::UdpSocket::read( void *pBuf, size_t nBytes, | 80 | size_t Bu::UdpSocket::read( void *pBuf, size_t nBytes, |
@@ -93,9 +84,15 @@ size_t Bu::UdpSocket::read( void *pBuf, size_t nBytes, | |||
93 | 84 | ||
94 | size_t Bu::UdpSocket::write( const void *pBuf, size_t nBytes ) | 85 | size_t Bu::UdpSocket::write( const void *pBuf, size_t nBytes ) |
95 | { | 86 | { |
96 | // name, the destination address, needs to be a class variable... | 87 | if( bBound ) |
97 | // return sendto( iUdpSocket, pBuf, nBytes, 0, | 88 | { |
98 | // (struct sockaddr *)&name, size ); | 89 | return sendto( iUdpSocket, pBuf, nBytes, 0, NULL, 0 ); |
90 | } | ||
91 | else | ||
92 | { | ||
93 | return sendto( iUdpSocket, pBuf, nBytes, 0, | ||
94 | (struct sockaddr*)paTarget, sizeof(struct sockaddr_in) ); | ||
95 | } | ||
99 | } | 96 | } |
100 | 97 | ||
101 | size_t Bu::UdpSocket::write( const void *pBuf, size_t nBytes, | 98 | size_t Bu::UdpSocket::write( const void *pBuf, size_t nBytes, |
diff --git a/src/udpsocket.h b/src/udpsocket.h index 4452458..0f81c38 100644 --- a/src/udpsocket.h +++ b/src/udpsocket.h | |||
@@ -13,7 +13,7 @@ namespace Bu | |||
13 | { | 13 | { |
14 | public: | 14 | public: |
15 | UdpSocket( int iUdpSocket ); | 15 | UdpSocket( int iUdpSocket ); |
16 | UdpSocket( const Bu::FString &sAddr, int iPort, bool bBroadcast ); | 16 | UdpSocket( const Bu::FString &sAddr, int iPort, int iFlags ); |
17 | virtual ~UdpSocket(); | 17 | virtual ~UdpSocket(); |
18 | 18 | ||
19 | virtual void close(); | 19 | virtual void close(); |
@@ -46,12 +46,23 @@ namespace Bu | |||
46 | 46 | ||
47 | virtual void setSize( long iSize ); | 47 | virtual void setSize( long iSize ); |
48 | 48 | ||
49 | enum { | ||
50 | // Flags | ||
51 | Read = 0x01, ///< Open udp socket for reading | ||
52 | Write = 0x02, ///< Open udp socket for writing | ||
53 | ReadWrite = 0x03, ///< Open for both read and write | ||
54 | Broadcast = 0x04, ///< Open for broadcast | ||
55 | }; | ||
56 | |||
57 | |||
49 | private: | 58 | private: |
50 | #ifdef WIN32 | 59 | #ifdef WIN32 |
51 | unsigned int iUdpSocket; | 60 | unsigned int iUdpSocket; |
52 | #else | 61 | #else |
53 | int iUdpSocket; | 62 | int iUdpSocket; |
54 | #endif | 63 | #endif |
64 | void *paTarget; | ||
65 | bool bBound; | ||
55 | }; | 66 | }; |
56 | }; | 67 | }; |
57 | 68 | ||