sa5webber
20th June 2012, 08:23
It's not done obviously but I'm trying to put together the basics for a test executive that creates multiple client connections where each client connects to a different server. So I've created a ConnectionMgr class that is supposed to handle each of the connections using a map that ties the serverName to a TcpClient class. In the TcpClient class I create the connections and the signals for receiving data.
My current problem is that I'm getting compile errors in the TcpClient class that says I have multiple definitions of ReadTcpData, Connected, Disconnected, etc. It appears that its having problems with the fact that I'm creating multiple instances of the TcpClient class.
.../QtProjects/B2TestSet-build-desktop-Desktop_Qt_4_8_1_for_GCC__Qt_SDK__Debug/moc_tcpclient.o:-1: In function `TcpClient::ReadTcpData()':
.../QtProjects/B2TestSet-build-desktop-Desktop_Qt_4_8_1_for_GCC__Qt_SDK__Debug/moc_tcpclient.cpp:104: multiple definition of `TcpClient::ReadTcpData()'
.../QtProjects/B2TestSet-build-desktop-Desktop_Qt_4_8_1_for_GCC__Qt_SDK__Debug/../B2TestSet/tcpclient.cpp:37: error: first defined here
.../QtProjects/B2TestSet-build-desktop-Desktop_Qt_4_8_1_for_GCC__Qt_SDK__Debug/moc_tcpclient.o:-1: In function `TcpClient::Connected()':
.../QtProjects/B2TestSet-build-desktop-Desktop_Qt_4_8_1_for_GCC__Qt_SDK__Debug/moc_tcpclient.cpp:110: multiple definition of `TcpClient::Connected()'
.../QtProjects/B2TestSet-build-desktop-Desktop_Qt_4_8_1_for_GCC__Qt_SDK__Debug/../B2TestSet/tcpclient.cpp:47: error: first defined here
.../QtProjects/B2TestSet-build-desktop-Desktop_Qt_4_8_1_for_GCC__Qt_SDK__Debug/moc_tcpclient.o:-1: In function `TcpClient::Disconnected()':
.../QtProjects/B2TestSet-build-desktop-Desktop_Qt_4_8_1_for_GCC__Qt_SDK__Debug/moc_tcpclient.cpp:116: multiple definition of `TcpClient::Disconnected()'
.../QtProjects/B2TestSet-build-desktop-Desktop_Qt_4_8_1_for_GCC__Qt_SDK__Debug/../B2TestSet/tcpclient.cpp:52: error: first defined here
.../QtProjects/B2TestSet-build-desktop-Desktop_Qt_4_8_1_for_GCC__Qt_SDK__Debug/moc_tcpclient.o:-1: In function `TcpClient::ErrHandler(QAbstractSocket::SocketErro r)':
.../QtProjects/B2TestSet-build-desktop-Desktop_Qt_4_8_1_for_GCC__Qt_SDK__Debug/moc_tcpclient.cpp:122: multiple definition of `TcpClient::ErrHandler(QAbstractSocket::SocketErro r)'
.../QtProjects/B2TestSet-build-desktop-Desktop_Qt_4_8_1_for_GCC__Qt_SDK__Debug/../B2TestSet/tcpclient.cpp:57: error: first defined here
I'm not sure if this is the best way to manage multiple client connections. If somebody has a better idea for a simpliar approach I would be interested.
mainwindow.cpp
***************************************
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
....
// Instantiate a connection manager
ConnectionMgr *conMgr = new ConnectionMgr(_serverMap, this);
conMgr->ConnectAll();
}
connectionmgr.cpp
***************************************
#include "connectionMgr.h"
ConnectionMgr::ConnectionMgr(std::map<string, string>serverMap, QObject *parent) :
QObject(parent)
{
_serverMap = serverMap;
}
void ConnectionMgr::ConnectAll()
{
map<string, string>::iterator it;
// Attempt to connect to the list of servers
// and add each client to a client map
for(it = _serverMap.begin(); it != _serverMap.end(); it++)
{
QString srvName = QString::fromStdString((*it).first);
QString srvInfo = QString::fromStdString((*it).second);
NetInfo netInfo = ParseSrvInfo( srvInfo );
TcpClient *tcpClient = new TcpClient(netInfo.ipAddr, netInfo.port, this);
_clientMap[srvName.toStdString()] = tcpClient;
}
}
connectionmgr.h
***************************************
#ifndef CONNECTIONMGR_H
#define CONNECTIONMGR_H
#include "qstring.h"
#include "qtcpsocket.h"
#include "qstringlist.h"
#include "tcpclient.h"
using namespace std;
struct NetInfo
{
QString ipAddr;
int port;
};
class ConnectionMgr : public QObject
{
Q_OBJECT
public:
ConnectionMgr(map<string, string>serverMap, QObject *parent = 0);
~ConnectionMgr();
TcpClient *GetTcpClient(QString srv);
void ConnectAll();
private:
map<string, string>_serverMap;
map<string, TcpClient*>_clientMap;
NetInfo GetSrvInfo( QString srvName );
NetInfo ParseSrvInfo( QString srvInfo );
};
#endif // CONNECTIONMGR_H
tcpclient.cpp
***************************************
#include "tcpclient.h"
TcpClient::TcpClient(QObject *parent) :
QObject(parent)
{
_isConnected = false;
}
TcpClient::TcpClient(QString ipAddr, int port, QObject *parent) :
QObject(parent)
{
_isConnected = false;
Connect(ipAddr, port);
}
void TcpClient::Connect(QString ipAddr, int port)
{
// When it did compile a segment fault occurs when the connect is called
_tcpClient = new QTcpSocket();
connect(_tcpClient, SIGNAL(readyRead()),SLOT(ReadTcpData()));
connect(_tcpClient, SIGNAL(connected()),SLOT(Connected()));
connect(_tcpClient, SIGNAL(disconnected()),SLOT(Disconnected()));
connect(_tcpClient, SIGNAL(error(QAbstractSocket::SocketError)),
SLOT(ErrHandler(QAbstractSocket::SocketError)));
_tcpClient->connectToHost(ipAddr, port);
}
qint64 TcpClient::Write(const char* data)
{
qint64 bytesWritten = 0;
if(_tcpClient->waitForConnected(5000))
bytesWritten = _tcpClient->write(data);
return bytesWritten;
}
void TcpClient::ReadTcpData()
{
QByteArray data = _tcpClient->readAll();
// Need to probably add an emit of some sort here
}
bool TcpClient::IsConnected()
{
return _isConnected;
}
void TcpClient::Connected()
{
_isConnected = true;
}
void TcpClient::Disconnected()
{
_isConnected = false;
}
void TcpClient::ErrHandler(QAbstractSocket::SocketError socketError)
{
QString errStr;
switch (socketError)
{
case QAbstractSocket::RemoteHostClosedError:
errStr = "TcpClient error: The remote host closed the connection.";
break;
case QAbstractSocket::HostNotFoundError:
errStr = "TcpClient error: The host was not found.";
break;
case QAbstractSocket::ConnectionRefusedError:
errStr = "TcpClient error: The connection was refused by the peer.";
break;
default:
errStr = tr("TcpClient error: %1").arg(_tcpClient->errorString());
break;
}
}
void TcpClient::Disconnect()
{
_tcpClient->disconnect();
}
tcpclient.h
***************************************
#ifndef TCPCLIENT_H
#define TCPCLIENT_H
#include <QObject>
#include "qtcpsocket.h"
using namespace std;
class TcpClient : public QObject
{
Q_OBJECT
public:
explicit TcpClient(QObject *parent = 0);
explicit TcpClient(QString ipAddr, int port, QObject *parent = 0);
~TcpClient();
void Connect(QString ipAddr, int port);
bool IsConnected();
qint64 Write(const char* data);
void Disconnect();
signals:
void ReadTcpData();
void Connected();
void Disconnected();
void ErrHandler(QAbstractSocket::SocketError socketError);
public slots:
private:
QTcpSocket* _tcpClient;
bool _isConnected;
};
#endif // TCPCLIENT_H
My current problem is that I'm getting compile errors in the TcpClient class that says I have multiple definitions of ReadTcpData, Connected, Disconnected, etc. It appears that its having problems with the fact that I'm creating multiple instances of the TcpClient class.
.../QtProjects/B2TestSet-build-desktop-Desktop_Qt_4_8_1_for_GCC__Qt_SDK__Debug/moc_tcpclient.o:-1: In function `TcpClient::ReadTcpData()':
.../QtProjects/B2TestSet-build-desktop-Desktop_Qt_4_8_1_for_GCC__Qt_SDK__Debug/moc_tcpclient.cpp:104: multiple definition of `TcpClient::ReadTcpData()'
.../QtProjects/B2TestSet-build-desktop-Desktop_Qt_4_8_1_for_GCC__Qt_SDK__Debug/../B2TestSet/tcpclient.cpp:37: error: first defined here
.../QtProjects/B2TestSet-build-desktop-Desktop_Qt_4_8_1_for_GCC__Qt_SDK__Debug/moc_tcpclient.o:-1: In function `TcpClient::Connected()':
.../QtProjects/B2TestSet-build-desktop-Desktop_Qt_4_8_1_for_GCC__Qt_SDK__Debug/moc_tcpclient.cpp:110: multiple definition of `TcpClient::Connected()'
.../QtProjects/B2TestSet-build-desktop-Desktop_Qt_4_8_1_for_GCC__Qt_SDK__Debug/../B2TestSet/tcpclient.cpp:47: error: first defined here
.../QtProjects/B2TestSet-build-desktop-Desktop_Qt_4_8_1_for_GCC__Qt_SDK__Debug/moc_tcpclient.o:-1: In function `TcpClient::Disconnected()':
.../QtProjects/B2TestSet-build-desktop-Desktop_Qt_4_8_1_for_GCC__Qt_SDK__Debug/moc_tcpclient.cpp:116: multiple definition of `TcpClient::Disconnected()'
.../QtProjects/B2TestSet-build-desktop-Desktop_Qt_4_8_1_for_GCC__Qt_SDK__Debug/../B2TestSet/tcpclient.cpp:52: error: first defined here
.../QtProjects/B2TestSet-build-desktop-Desktop_Qt_4_8_1_for_GCC__Qt_SDK__Debug/moc_tcpclient.o:-1: In function `TcpClient::ErrHandler(QAbstractSocket::SocketErro r)':
.../QtProjects/B2TestSet-build-desktop-Desktop_Qt_4_8_1_for_GCC__Qt_SDK__Debug/moc_tcpclient.cpp:122: multiple definition of `TcpClient::ErrHandler(QAbstractSocket::SocketErro r)'
.../QtProjects/B2TestSet-build-desktop-Desktop_Qt_4_8_1_for_GCC__Qt_SDK__Debug/../B2TestSet/tcpclient.cpp:57: error: first defined here
I'm not sure if this is the best way to manage multiple client connections. If somebody has a better idea for a simpliar approach I would be interested.
mainwindow.cpp
***************************************
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
....
// Instantiate a connection manager
ConnectionMgr *conMgr = new ConnectionMgr(_serverMap, this);
conMgr->ConnectAll();
}
connectionmgr.cpp
***************************************
#include "connectionMgr.h"
ConnectionMgr::ConnectionMgr(std::map<string, string>serverMap, QObject *parent) :
QObject(parent)
{
_serverMap = serverMap;
}
void ConnectionMgr::ConnectAll()
{
map<string, string>::iterator it;
// Attempt to connect to the list of servers
// and add each client to a client map
for(it = _serverMap.begin(); it != _serverMap.end(); it++)
{
QString srvName = QString::fromStdString((*it).first);
QString srvInfo = QString::fromStdString((*it).second);
NetInfo netInfo = ParseSrvInfo( srvInfo );
TcpClient *tcpClient = new TcpClient(netInfo.ipAddr, netInfo.port, this);
_clientMap[srvName.toStdString()] = tcpClient;
}
}
connectionmgr.h
***************************************
#ifndef CONNECTIONMGR_H
#define CONNECTIONMGR_H
#include "qstring.h"
#include "qtcpsocket.h"
#include "qstringlist.h"
#include "tcpclient.h"
using namespace std;
struct NetInfo
{
QString ipAddr;
int port;
};
class ConnectionMgr : public QObject
{
Q_OBJECT
public:
ConnectionMgr(map<string, string>serverMap, QObject *parent = 0);
~ConnectionMgr();
TcpClient *GetTcpClient(QString srv);
void ConnectAll();
private:
map<string, string>_serverMap;
map<string, TcpClient*>_clientMap;
NetInfo GetSrvInfo( QString srvName );
NetInfo ParseSrvInfo( QString srvInfo );
};
#endif // CONNECTIONMGR_H
tcpclient.cpp
***************************************
#include "tcpclient.h"
TcpClient::TcpClient(QObject *parent) :
QObject(parent)
{
_isConnected = false;
}
TcpClient::TcpClient(QString ipAddr, int port, QObject *parent) :
QObject(parent)
{
_isConnected = false;
Connect(ipAddr, port);
}
void TcpClient::Connect(QString ipAddr, int port)
{
// When it did compile a segment fault occurs when the connect is called
_tcpClient = new QTcpSocket();
connect(_tcpClient, SIGNAL(readyRead()),SLOT(ReadTcpData()));
connect(_tcpClient, SIGNAL(connected()),SLOT(Connected()));
connect(_tcpClient, SIGNAL(disconnected()),SLOT(Disconnected()));
connect(_tcpClient, SIGNAL(error(QAbstractSocket::SocketError)),
SLOT(ErrHandler(QAbstractSocket::SocketError)));
_tcpClient->connectToHost(ipAddr, port);
}
qint64 TcpClient::Write(const char* data)
{
qint64 bytesWritten = 0;
if(_tcpClient->waitForConnected(5000))
bytesWritten = _tcpClient->write(data);
return bytesWritten;
}
void TcpClient::ReadTcpData()
{
QByteArray data = _tcpClient->readAll();
// Need to probably add an emit of some sort here
}
bool TcpClient::IsConnected()
{
return _isConnected;
}
void TcpClient::Connected()
{
_isConnected = true;
}
void TcpClient::Disconnected()
{
_isConnected = false;
}
void TcpClient::ErrHandler(QAbstractSocket::SocketError socketError)
{
QString errStr;
switch (socketError)
{
case QAbstractSocket::RemoteHostClosedError:
errStr = "TcpClient error: The remote host closed the connection.";
break;
case QAbstractSocket::HostNotFoundError:
errStr = "TcpClient error: The host was not found.";
break;
case QAbstractSocket::ConnectionRefusedError:
errStr = "TcpClient error: The connection was refused by the peer.";
break;
default:
errStr = tr("TcpClient error: %1").arg(_tcpClient->errorString());
break;
}
}
void TcpClient::Disconnect()
{
_tcpClient->disconnect();
}
tcpclient.h
***************************************
#ifndef TCPCLIENT_H
#define TCPCLIENT_H
#include <QObject>
#include "qtcpsocket.h"
using namespace std;
class TcpClient : public QObject
{
Q_OBJECT
public:
explicit TcpClient(QObject *parent = 0);
explicit TcpClient(QString ipAddr, int port, QObject *parent = 0);
~TcpClient();
void Connect(QString ipAddr, int port);
bool IsConnected();
qint64 Write(const char* data);
void Disconnect();
signals:
void ReadTcpData();
void Connected();
void Disconnected();
void ErrHandler(QAbstractSocket::SocketError socketError);
public slots:
private:
QTcpSocket* _tcpClient;
bool _isConnected;
};
#endif // TCPCLIENT_H