bug fix with connection less protocol messages system at the client

This commit is contained in:
Volker Fischer 2011-04-23 20:44:56 +00:00
parent 5e82a73b17
commit c4818c55e0

View File

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