/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer * * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or * (at your option) any later version. The full license is in LICENSE file * included with this distribution, and on the openscenegraph.org website. * * osgVisual requires for some proprietary modules a license from the correspondig manufacturer. * You have to aquire licenses for all used proprietary modules. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * OpenSceneGraph Public License for more details. */ #include "dataIO_clusterUDP_Transmission.h" using namespace osgVisual; Broadcaster::Broadcaster() { _initialized = false; _destinationAddress = 0; requestedWSAVersion = MAKEWORD(2,0); } Broadcaster::~Broadcaster() { closesocket( _so); } bool Broadcaster::init(const short port_) { WSADATA wsaData; // First, we start up Winsock WSAStartup(requestedWSAVersion, &wsaData); if( port_ == 0 ) { OSG_NOTIFY( osg::FATAL ) << "ERROR: Broadcaster::init() - port not defined: " << std::endl; return false; } // Create Socket if( (_so = socket( AF_INET, SOCK_DGRAM, 0 )) < 0 ) { OSG_NOTIFY( osg::FATAL ) << "ERROR: Broadcaster::init() - Unable to create socket!" << std::endl; return false; } const BOOL on = TRUE; // Set Socket options setsockopt( _so, SOL_SOCKET, SO_REUSEADDR, (const char *) &on, sizeof(int)); saddr.sin_family = AF_INET; // Internetwork UDP, TCP etc. saddr.sin_port = htons( port_ ); // Port festlegen if( _destinationAddress == 0 ) // Wenn keine Zieladresse festgelegt: Broadcasten { setsockopt( _so, SOL_SOCKET, SO_BROADCAST, (const char *) &on, sizeof(int)); saddr.sin_addr.s_addr = htonl(INADDR_BROADCAST); } // Print out destination address unsigned char *ptr = (unsigned char *)&saddr.sin_addr.s_addr; OSG_NOTIFY( osg::ALWAYS ) << "INFO: Broadcaster::init() - Broadcast address = " << (unsigned int)ptr[0] << "." << (unsigned int)ptr[1] << "." << (unsigned int)ptr[2] << "." << (unsigned int)ptr[3] << std::endl; // Note: Initialization finished. _initialized = true; return _initialized; } void Broadcaster::setDestinationHost( const char *hostname ) { struct hostent *h; if( (h = gethostbyname( hostname )) == 0L ) { OSG_NOTIFY( osg::FATAL ) << "ERROR: Broadcaster::setHost() - Cannot resolve an address for " << hostname; _destinationAddress = 0; } else _destinationAddress = *(( unsigned long *)h->h_addr); } void Broadcaster::transmitBuffer( const char* buffer_, const unsigned int size_ ) { if(!_initialized) { OSG_NOTIFY( osg::FATAL ) << "ERROR: Broadcaster not initialized!" << std::endl; return; } if( buffer_ == NULL ) { OSG_NOTIFY( osg::FATAL ) << "ERROR: Broadcaster::transmitBuffer() - No buffer" << std::endl; return; } unsigned int addrSize = sizeof( SOCKADDR_IN ); sendto( _so, buffer_, size_, 0, (struct sockaddr *)&saddr, addrSize ); int err = WSAGetLastError (); if (err!=0) OSG_NOTIFY( osg::FATAL ) << "ERROR: Broadcaster::transmitBuffer() - Error #: " << err << std::endl; } // //-------------------------------------------------------- // Receiver::Receiver( void ) { _initialized = false; requestedWSAVersion = MAKEWORD(2,0); } Receiver::~Receiver( void ) { closesocket( _so); } bool Receiver::init( const short port_ ) { WSADATA wsaData; // First, we start up Winsock WSAStartup(requestedWSAVersion, &wsaData); if( port_ == 0 ) { OSG_NOTIFY( osg::FATAL ) << "ERROR: Receiver::init() - port not defined: " << std::endl; return false; } // Create Socket if( (_so = socket( AF_INET, SOCK_DGRAM, 0 )) < 0 ) { OSG_NOTIFY( osg::FATAL ) << "ERROR: Receiver::init() -Could not create Socket" << std::endl; return false; } // Set Socket Protocolfamily and Protocoldata (IP address, port, etc.) //// Protokollfamilie saddr.sin_family = AF_INET; //// Port: saddr.sin_port = htons( port_ ); // The htons function converts a u_short from host to TCP/IP network byte order (which is big-endian) //////Socketadresse. INADDR_ANY ist das Schlüsselwort für 0x00000000 und bindet den Socket auf alle lokalen IP-Adressen: saddr.sin_addr.s_addr = htonl(INADDR_ANY); // The htonl function converts a u_long from host to TCP/IP network byte order (which is big endian). // Bind socket to local address and port. if( bind( _so, (struct sockaddr *)&saddr, sizeof( saddr )) < 0 ) { OSG_NOTIFY( osg::FATAL ) << "ERROR: Receiver::init() - Could not bind Socket" << std::endl; return false; } // Note: Initialization finished. _initialized = true; return _initialized; } void Receiver::waitBlockingforSocketData( std::stringstream& writeInto_ ) { if(!_initialized) { OSG_NOTIFY( osg::FATAL ) << "ERROR: Receiver not initialized!" << std::endl; return; } // ?? Size des Addresspaketes ermitteln int size = sizeof( struct sockaddr_in ); fd_set fdset; // Filedescriptor Set FD_ZERO( &fdset ); // Initialisiert das FDS als Null FD_SET( _so, &fdset ); // Fügt dem FDS ein FileDescriptor hinzu // Set Timeintervall for select() timeout struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 0; // In einer Schleife: Solange lesen bis keine Daten mehr in dem Socket warten. while( select( _so, &fdset, 0L, 0L, &tv ) ) // <0: error, =0 timeout, >0: socket to read { if( FD_ISSET( _so, &fdset ) ) { int ret = recvfrom( _so, buffer, 65000, 0, (sockaddr*)&saddr, &size ); // check for size if (ret > 0) { writeInto_.str(""); OSG_NOTIFY( osg::INFO ) << "Receiver::waitBlockingforSocketData() - Empfangene Bytes:" << ret << std::endl; for(int i=0;i