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:isconnected()':
.../QtProjects/B2TestSet-build-desktop-Desktop_Qt_4_8_1_for_GCC__Qt_SDK__Debug/moc_tcpclient.cpp:116: multiple definition of `TcpClient:isconnected()'
.../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.

Qt Code:
  1. mainwindow.cpp
  2. ***************************************
  3.  
  4. MainWindow::MainWindow(QWidget *parent) :
  5. QMainWindow(parent),
  6. ui(new Ui::MainWindow)
  7. {
  8. ui->setupUi(this);
  9.  
  10. ....
  11.  
  12. // Instantiate a connection manager
  13. ConnectionMgr *conMgr = new ConnectionMgr(_serverMap, this);
  14. conMgr->ConnectAll();
  15. }
  16.  
  17. connectionmgr.cpp
  18. ***************************************
  19. #include "connectionMgr.h"
  20.  
  21. ConnectionMgr::ConnectionMgr(std::map<string, string>serverMap, QObject *parent) :
  22. QObject(parent)
  23. {
  24. _serverMap = serverMap;
  25. }
  26.  
  27. void ConnectionMgr::ConnectAll()
  28. {
  29. map<string, string>::iterator it;
  30.  
  31. // Attempt to connect to the list of servers
  32. // and add each client to a client map
  33. for(it = _serverMap.begin(); it != _serverMap.end(); it++)
  34. {
  35. QString srvName = QString::fromStdString((*it).first);
  36. QString srvInfo = QString::fromStdString((*it).second);
  37. NetInfo netInfo = ParseSrvInfo( srvInfo );
  38.  
  39. TcpClient *tcpClient = new TcpClient(netInfo.ipAddr, netInfo.port, this);
  40. _clientMap[srvName.toStdString()] = tcpClient;
  41. }
  42. }
  43.  
  44. connectionmgr.h
  45. ***************************************
  46. #ifndef CONNECTIONMGR_H
  47. #define CONNECTIONMGR_H
  48.  
  49. #include "qstring.h"
  50. #include "qtcpsocket.h"
  51. #include "qstringlist.h"
  52. #include "tcpclient.h"
  53.  
  54. using namespace std;
  55.  
  56. struct NetInfo
  57. {
  58. QString ipAddr;
  59. int port;
  60. };
  61.  
  62. class ConnectionMgr : public QObject
  63. {
  64. Q_OBJECT
  65.  
  66. public:
  67. ConnectionMgr(map<string, string>serverMap, QObject *parent = 0);
  68. ~ConnectionMgr();
  69.  
  70. TcpClient *GetTcpClient(QString srv);
  71. void ConnectAll();
  72.  
  73. private:
  74. map<string, string>_serverMap;
  75. map<string, TcpClient*>_clientMap;
  76.  
  77. NetInfo GetSrvInfo( QString srvName );
  78. NetInfo ParseSrvInfo( QString srvInfo );
  79. };
  80.  
  81. #endif // CONNECTIONMGR_H
  82.  
  83. tcpclient.cpp
  84. ***************************************
  85. #include "tcpclient.h"
  86.  
  87. TcpClient::TcpClient(QObject *parent) :
  88. QObject(parent)
  89. {
  90. _isConnected = false;
  91. }
  92.  
  93. TcpClient::TcpClient(QString ipAddr, int port, QObject *parent) :
  94. QObject(parent)
  95. {
  96. _isConnected = false;
  97. Connect(ipAddr, port);
  98. }
  99.  
  100. void TcpClient::Connect(QString ipAddr, int port)
  101. {
  102. // When it did compile a segment fault occurs when the connect is called
  103. _tcpClient = new QTcpSocket();
  104. connect(_tcpClient, SIGNAL(readyRead()),SLOT(ReadTcpData()));
  105. connect(_tcpClient, SIGNAL(connected()),SLOT(Connected()));
  106. connect(_tcpClient, SIGNAL(disconnected()),SLOT(Disconnected()));
  107. connect(_tcpClient, SIGNAL(error(QAbstractSocket::SocketError)),
  108. SLOT(ErrHandler(QAbstractSocket::SocketError)));
  109. _tcpClient->connectToHost(ipAddr, port);
  110. }
  111.  
  112. qint64 TcpClient::Write(const char* data)
  113. {
  114. qint64 bytesWritten = 0;
  115. if(_tcpClient->waitForConnected(5000))
  116. bytesWritten = _tcpClient->write(data);
  117.  
  118. return bytesWritten;
  119. }
  120.  
  121. void TcpClient::ReadTcpData()
  122. {
  123. QByteArray data = _tcpClient->readAll();
  124. // Need to probably add an emit of some sort here
  125. }
  126.  
  127. bool TcpClient::IsConnected()
  128. {
  129. return _isConnected;
  130. }
  131.  
  132. void TcpClient::Connected()
  133. {
  134. _isConnected = true;
  135. }
  136.  
  137. void TcpClient::Disconnected()
  138. {
  139. _isConnected = false;
  140. }
  141.  
  142. void TcpClient::ErrHandler(QAbstractSocket::SocketError socketError)
  143. {
  144. QString errStr;
  145. switch (socketError)
  146. {
  147. case QAbstractSocket::RemoteHostClosedError:
  148. errStr = "TcpClient error: The remote host closed the connection.";
  149. break;
  150. case QAbstractSocket::HostNotFoundError:
  151. errStr = "TcpClient error: The host was not found.";
  152. break;
  153. case QAbstractSocket::ConnectionRefusedError:
  154. errStr = "TcpClient error: The connection was refused by the peer.";
  155. break;
  156. default:
  157. errStr = tr("TcpClient error: %1").arg(_tcpClient->errorString());
  158. break;
  159. }
  160. }
  161.  
  162. void TcpClient::Disconnect()
  163. {
  164. _tcpClient->disconnect();
  165. }
  166.  
  167. tcpclient.h
  168. ***************************************
  169. #ifndef TCPCLIENT_H
  170. #define TCPCLIENT_H
  171.  
  172. #include <QObject>
  173. #include "qtcpsocket.h"
  174.  
  175. using namespace std;
  176.  
  177. class TcpClient : public QObject
  178. {
  179. Q_OBJECT
  180. public:
  181. explicit TcpClient(QObject *parent = 0);
  182. explicit TcpClient(QString ipAddr, int port, QObject *parent = 0);
  183. ~TcpClient();
  184.  
  185. void Connect(QString ipAddr, int port);
  186. bool IsConnected();
  187. qint64 Write(const char* data);
  188. void Disconnect();
  189.  
  190. signals:
  191. void ReadTcpData();
  192. void Connected();
  193. void Disconnected();
  194. void ErrHandler(QAbstractSocket::SocketError socketError);
  195.  
  196. public slots:
  197.  
  198. private:
  199. QTcpSocket* _tcpClient;
  200. bool _isConnected;
  201. };
  202.  
  203. #endif // TCPCLIENT_H
To copy to clipboard, switch view to plain text mode