diff --git a/src/socket.cpp b/src/socket.cpp index d0f7cb45..20d469a4 100755 --- a/src/socket.cpp +++ b/src/socket.cpp @@ -1,169 +1,171 @@ -/******************************************************************************\ - * Copyright (c) 2004-2011 - * - * Author(s): - * Volker Fischer - * - ****************************************************************************** - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * This program 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 GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * -\******************************************************************************/ - -#include "socket.h" -#include "server.h" - - -/* Implementation *************************************************************/ -void CSocket::Init ( const quint16 iPortNumber ) -{ - // allocate memory for network receive and send buffer in samples - vecbyRecBuf.Init ( MAX_SIZE_BYTES_NETW_BUF ); - - // initialize the listening socket - bool bSuccess; - if ( bIsClient ) - { - // Per definition use the port number plus ten for the client to make - // it possible to run server and client on the same computer. If the - // port is not available, try "NUM_SOCKET_PORTS_TO_TRY" times with - // incremented port numbers - quint16 iClientPortIncrement = 10; // start value: port nubmer plus ten - bSuccess = false; // initialization for while loop - while ( !bSuccess && - ( iClientPortIncrement <= NUM_SOCKET_PORTS_TO_TRY ) ) - { - bSuccess = SocketDevice.bind ( - QHostAddress( QHostAddress::Any ), - iPortNumber + iClientPortIncrement ); - - iClientPortIncrement++; - } - } - else - { - // for the server, only try the given port number and do not try out - // other port numbers to bind since it is imporatant that the server - // gets the desired port number - bSuccess = SocketDevice.bind ( - QHostAddress ( QHostAddress::Any ), iPortNumber ); - } - - if ( !bSuccess ) - { - // we cannot bind socket, throw error - throw CGenErr ( "Cannot bind the socket (maybe " - "the software is already running).", "Network Error" ); - } - - // connect the "activated" signal - QObject::connect ( &SocketDevice, SIGNAL ( readyRead() ), - this, SLOT ( OnDataReceived() ) ); -} - -void CSocket::SendPacket ( const CVector& vecbySendBuf, - const CHostAddress& HostAddr ) -{ - QMutexLocker locker ( &Mutex ); - - const int iVecSizeOut = vecbySendBuf.Size(); - - if ( iVecSizeOut != 0 ) - { - // send packet through network (we have to convert the constant unsigned - // char vector in "const char*", for this we first convert the const - // uint8_t vector in a read/write uint8_t vector and then do the cast to - // const char*) - SocketDevice.writeDatagram ( - (const char*) &( (CVector) vecbySendBuf )[0], - iVecSizeOut, - HostAddr.InetAddr, - HostAddr.iPort ); - } -} - -void CSocket::OnDataReceived() -{ - while ( SocketDevice.hasPendingDatagrams() ) - { - QHostAddress SenderAddress; - quint16 SenderPort; - - // read block from network interface and query address of sender - const int iNumBytesRead = - SocketDevice.readDatagram ( (char*) &vecbyRecBuf[0], - MAX_SIZE_BYTES_NETW_BUF, - &SenderAddress, - &SenderPort ); - - // check if an error occurred - if ( iNumBytesRead < 0 ) - { - return; - } - - // convert address of client - const CHostAddress RecHostAddr ( SenderAddress, SenderPort ); - - if ( bIsClient ) - { - // client: - // check if packet comes from the server we want to connect - if ( !( pChannel->GetAddress() == RecHostAddr ) ) - { - // this is an unknown address, try to parse connection less - // message - pConnLessProtocol->ParseConnectionLessMessage ( vecbyRecBuf, - iNumBytesRead, - RecHostAddr ); - - // do not perform any other action on this received packet - return; - } - - switch ( pChannel->PutData ( vecbyRecBuf, iNumBytesRead ) ) - { - case PS_AUDIO_OK: - PostWinMessage ( MS_JIT_BUF_PUT, MUL_COL_LED_GREEN ); - break; - - case PS_AUDIO_ERR: - case PS_GEN_ERROR: - PostWinMessage ( MS_JIT_BUF_PUT, MUL_COL_LED_RED ); - break; - - case PS_PROT_ERR: - PostWinMessage ( MS_JIT_BUF_PUT, MUL_COL_LED_YELLOW ); - break; - - default: - // other put data states need not to be considered here - break; - } - } - else - { - // server: - if ( pServer->PutData ( vecbyRecBuf, iNumBytesRead, RecHostAddr ) ) - { - // this was an audio packet, start server - // tell the server object to wake up if it - // is in sleep mode (Qt will delete the event object when done) - QCoreApplication::postEvent ( pServer, - new CLlconEvent ( MS_PACKET_RECEIVED, 0, 0 ) ); - } - } - } -} +/******************************************************************************\ + * Copyright (c) 2004-2011 + * + * Author(s): + * Volker Fischer + * + ****************************************************************************** + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * This program 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 GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * +\******************************************************************************/ + +#include "socket.h" +#include "server.h" + + +/* Implementation *************************************************************/ +void CSocket::Init ( const quint16 iPortNumber ) +{ + // allocate memory for network receive and send buffer in samples + vecbyRecBuf.Init ( MAX_SIZE_BYTES_NETW_BUF ); + + // initialize the listening socket + bool bSuccess; + if ( bIsClient ) + { + // Per definition use the port number plus ten for the client to make + // it possible to run server and client on the same computer. If the + // port is not available, try "NUM_SOCKET_PORTS_TO_TRY" times with + // incremented port numbers + quint16 iClientPortIncrement = 10; // start value: port nubmer plus ten + bSuccess = false; // initialization for while loop + while ( !bSuccess && + ( iClientPortIncrement <= NUM_SOCKET_PORTS_TO_TRY ) ) + { + bSuccess = SocketDevice.bind ( + QHostAddress( QHostAddress::Any ), + iPortNumber + iClientPortIncrement ); + + iClientPortIncrement++; + } + } + else + { + // for the server, only try the given port number and do not try out + // other port numbers to bind since it is imporatant that the server + // gets the desired port number + bSuccess = SocketDevice.bind ( + QHostAddress ( QHostAddress::Any ), iPortNumber ); + } + + if ( !bSuccess ) + { + // we cannot bind socket, throw error + throw CGenErr ( "Cannot bind the socket (maybe " + "the software is already running).", "Network Error" ); + } + + // connect the "activated" signal + QObject::connect ( &SocketDevice, SIGNAL ( readyRead() ), + this, SLOT ( OnDataReceived() ) ); +} + +void CSocket::SendPacket ( const CVector& vecbySendBuf, + const CHostAddress& HostAddr ) +{ + QMutexLocker locker ( &Mutex ); + + const int iVecSizeOut = vecbySendBuf.Size(); + + if ( iVecSizeOut != 0 ) + { + // send packet through network (we have to convert the constant unsigned + // char vector in "const char*", for this we first convert the const + // uint8_t vector in a read/write uint8_t vector and then do the cast to + // const char*) + SocketDevice.writeDatagram ( + (const char*) &( (CVector) vecbySendBuf )[0], + iVecSizeOut, + HostAddr.InetAddr, + HostAddr.iPort ); + } +} + +void CSocket::OnDataReceived() +{ + while ( SocketDevice.hasPendingDatagrams() ) + { + QHostAddress SenderAddress; + quint16 SenderPort; + + // read block from network interface and query address of sender + const int iNumBytesRead = + SocketDevice.readDatagram ( (char*) &vecbyRecBuf[0], + MAX_SIZE_BYTES_NETW_BUF, + &SenderAddress, + &SenderPort ); + + // check if an error occurred + if ( iNumBytesRead < 0 ) + { + return; + } + + // convert address of client + const CHostAddress RecHostAddr ( SenderAddress, SenderPort ); + + if ( bIsClient ) + { + // client: + // check if packet comes from the server we want to connect and that + // the channel is enabled + if ( !( pChannel->GetAddress() == RecHostAddr ) || + !pChannel->IsEnabled() ) + { + // this is an unknown address, try to parse connection less + // message + pConnLessProtocol->ParseConnectionLessMessage ( vecbyRecBuf, + iNumBytesRead, + RecHostAddr ); + + // do not perform any other action on this received packet + return; + } + + switch ( pChannel->PutData ( vecbyRecBuf, iNumBytesRead ) ) + { + case PS_AUDIO_OK: + PostWinMessage ( MS_JIT_BUF_PUT, MUL_COL_LED_GREEN ); + break; + + case PS_AUDIO_ERR: + case PS_GEN_ERROR: + PostWinMessage ( MS_JIT_BUF_PUT, MUL_COL_LED_RED ); + break; + + case PS_PROT_ERR: + PostWinMessage ( MS_JIT_BUF_PUT, MUL_COL_LED_YELLOW ); + break; + + default: + // other put data states need not to be considered here + break; + } + } + else + { + // server: + if ( pServer->PutData ( vecbyRecBuf, iNumBytesRead, RecHostAddr ) ) + { + // this was an audio packet, start server + // tell the server object to wake up if it + // is in sleep mode (Qt will delete the event object when done) + QCoreApplication::postEvent ( pServer, + new CLlconEvent ( MS_PACKET_RECEIVED, 0, 0 ) ); + } + } + } +}