bug fix with connection less protocol messages system at the client
This commit is contained in:
parent
5e82a73b17
commit
c4818c55e0
1 changed files with 171 additions and 169 deletions
340
src/socket.cpp
340
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<uint8_t>& 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<uint8_t>) 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<uint8_t>& 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<uint8_t>) 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 ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue