PDA

View Full Version : TCP Server and client communications



speedofdark
1st June 2011, 20:26
I have a program to setup TCP clients and servers using threading and I can not figure out why it is behaving in the following way:
When the program first runs I am able to send files or messages from the client to the server or from the server to the client. But once I send anything from the server to the client, that particular client is no longer able to send either files or messages to the server.

I'm currently using the signals/slots method and can not see how it is becoming essentially biased.

Any ideas on what could be causing my problems?

Thank You,
Rod

squidge
1st June 2011, 21:04
No idea, perhaps you could post the relevent parts of code?

speedofdark
1st June 2011, 22:15
Here are two portions of my threading code. I'm afraid that the entire program is a bit intertwined. If this is not enough information I can post other parts as well.



#include "cio_thread.h"

#include <QTcpSocket>
#include <QHostAddress>
#include <QEvent>

#include "cio_event.h"

//-----------------------------------------------------------------------------
// Constructor
//-----------------------------------------------------------------------------

CIO_Thread::CIO_Thread( QObject* Parent ) : QThread( Parent )
{
pSocket = 0;
Terminating = false;
}

//-----------------------------------------------------------------------------
// Connection
//-----------------------------------------------------------------------------

const char* CIO_Thread::Socket_State()
{
if ( pSocket == 0 ) return "The socket is unitialized";

switch ( pSocket->state() )
{
case QAbstractSocket::UnconnectedState :
return "The socket is not connected";
case QAbstractSocket::HostLookupState :
return "The socket is performing a host name lookup";
case QAbstractSocket::ConnectingState :
return "The socket has started establishing a connection";
case QAbstractSocket::ConnectedState :
return "A connection is established";
case QAbstractSocket::BoundState :
return "The socket is bound to an address and port (for servers)";
case QAbstractSocket::ClosingState :
return "The socket is about to close (data may still be waiting to be written)";
case QAbstractSocket::ListeningState :
return "For internal use only";
default:
return "The socket state is unknown";
}
}

QString CIO_Thread::Socket_Peer()
{
if ( pSocket == 0 ) return "Nobody";

QString Peer = "Name = " + pSocket->peerName() + ", ";
Peer += "Address = " + pSocket->peerAddress().toString() + ", ";
Peer += "Port = " + QString::number( pSocket->peerPort() );

return Peer;
}

void CIO_Thread::Socket_Disconnect()
{
pSocket->disconnectFromHost();

if ( pSocket->state() != QAbstractSocket::UnconnectedState )
{
pSocket->waitForDisconnected();
}

pSocket = 0;

emit Termination_Emit();
}

void CIO_Thread::Disconnect_Internal( bool Notify_Buddy )
{
if ( Notify_Buddy ) Data.Command_Write_Terminate();

Terminating = true;
quit();
}

//-----------------------------------------------------------------------------

bool CIO_Thread::Connect()
{
Terminating = false;
start();

return true;
}

void CIO_Thread::Disconnect()
{
if ( !isRunning() ) return;

Termination_Message = "Disconnection by request (socket state = ";
Termination_Message += Socket_State();
Termination_Message += ").";

Disconnect_Internal( true );
}

//-----------------------------------------------------------------------------
// Connection States
//-----------------------------------------------------------------------------

CIO_Thread::Connection_States CIO_Thread::Connection_State()
{
if ( !isRunning() ) return DISCONNECTED;
if ( pSocket == 0 ) return DISCONNECTED;

if ( pSocket->state() == QAbstractSocket::ConnectedState ) return CONNECTED;

return CONNECTING;
}

//-----------------------------------------------------------------------------
// Data
//-----------------------------------------------------------------------------

bool CIO_Thread::DW_Terminate()
{
if ( !Data.Error_Is() ) return false;

Termination_Message = Data.Error_Get();
Disconnect_Internal( true );

return true;
}

void CIO_Thread::Data_Write()
{
while ( Data.Messages_Out_Write() );
if ( DW_Terminate() ) return;

while ( Data.XML_Out_Write() );
if ( DW_Terminate() ) return;

while ( Data.File_Out_Write() );
if ( DW_Terminate() ) return;

pSocket->flush();
}

//-----------------------------------------------------------------------------

void CIO_Thread::Path_Set( const QString& Path )
{
Data.File_Save_Path = Path;
}

QString CIO_Thread::Path_Get()
{
return Data.File_Save_Path;
}

//-----------------------------------------------------------------------------
// Overrides
//-----------------------------------------------------------------------------

void CIO_Thread::run()
{
Data.Stream_Activate( pSocket );

// Start Loop

exec();

// Blow this taco stand

Socket_Disconnect();
}

void CIO_Thread::customEvent( QEvent* event )
{
if ( Terminating ) return;
if ( pSocket == 0 ) return;

event->accept();

// Process Command

CIO_Event* pEvent = (CIO_Event*) event;

switch ( pEvent->Command )
{
case CIO_Event::WRITE_MESSAGE :
Data.Messages_Out_Add( pEvent->Text );
break;
case CIO_Event::WRITE_XML :
Data.XML_Out_Add( pEvent->xDoc );
break;
case CIO_Event::WRITE_FILE :
Data.File_Out_Add( pEvent->Text );
break;
}

Data_Write();
}

//-----------------------------------------------------------------------------
// Slots
//-----------------------------------------------------------------------------

Q_DECLARE_METATYPE( QAbstractSocket::SocketError )

void CIO_Thread::Slots_Connect( QTcpSocket& Socket )
{
pSocket = &Socket;

// Initialize Socket Handlers

connect
(
pSocket, SIGNAL( hostFound () ),
this , SLOT ( Socket_Host_Found() ),
Qt::QueuedConnection
);

connect
(
pSocket, SIGNAL( connected () ),
this , SLOT ( Socket_Connected() ),
Qt::QueuedConnection
);

qRegisterMetaType<QAbstractSocket::SocketError>( "QAbstractSocket::SocketError" );

connect
(
pSocket, SIGNAL( error ( QAbstractSocket::SocketError ) ),
this , SLOT ( Socket_Error( ) ),
Qt::QueuedConnection
);

// Initialize Data Handlers

connect
(
pSocket, SIGNAL( readyRead() ),
this , SLOT ( Data_Read() ),
Qt::QueuedConnection
);

}

//-----------------------------------------------------------------------------

void CIO_Thread::Socket_Host_Found()
{
Host_Found_Emit();
}

void CIO_Thread::Socket_Connected()
{
emit Connected( Socket_State() );
}

void CIO_Thread::Socket_Error()
{
if ( pSocket == 0 ) return;

Termination_Message = "Socket Error - " + pSocket->errorString();
Disconnect_Internal( false );
}

//-----------------------------------------------------------------------------

void CIO_Thread::Data_Read()
{
if ( Terminating ) return;

// Process incoming data

bool Stuff = pSocket->bytesAvailable() > 0;

while ( Stuff )
{
if ( !Data.Command_Read() )
{
Termination_Message = Data.Error_Get();
Disconnect_Internal( true );
return;
}

if ( Data.Command_Is_Terminate() )
{
Termination_Message = "Peer requested termination.";
Disconnect_Internal( false );
return;
}

Stuff = pSocket->bytesAvailable() > 0;
}

// Notify your master

while ( Data.Messages_In_Present() )
{
Message_Read_Emit( Data.Messages_In_Get() );
}

while ( Data.XML_In_Present() )
{
XML_Read_Emit( Data.XML_In_Get() );
}

while ( Data.File_In_Present() )
{
File_Read_Emit( Data.File_In_Get() );
}
}

void CIO_Thread::Data_Write_Message( const QString& Message )
{
Data.Message_Write( Message );
}

digimonkey
7th November 2014, 09:56
Did you manage to solve this?

ChrisW67
8th November 2014, 00:49
Given the three years that have elapsed I guess the answer is probably yes.

Your problem, whatever it is, is unlikely to be identical. Why not start your own thread and explain how you need help?
As a starting hint: You rarely need threads anywhere near Qt networking.