diff options
| -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 | ||
