diff --git a/.cproject b/.cproject
index 7ddc2155..c4d3a86e 100644
--- a/.cproject
+++ b/.cproject
@@ -1,215 +1,215 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- cmake
- -E chdir build/ cmake -G "MinGW Makefiles" -D CMAKE_BUILD_TYPE=Debug ../
-
- true
- false
- true
-
-
- cmake
- -E chdir build/ cmake -G "MinGW Makefiles" -D CMAKE_BUILD_TYPE=Release ../
-
- true
- false
- true
-
-
- cmake
- -E chdir build/ cmake -G "Unix Makefiles" -D CMAKE_BUILD_TYPE=Debug ../
-
- true
- false
- true
-
-
- cmake
- -E chdir build/ cmake -G "Unix Makefiles" -D CMAKE_BUILD_TYPE=Release ../
-
- true
- false
- true
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- cmake
- -E chdir build/ cmake -G "MinGW Makefiles" -D CMAKE_BUILD_TYPE=Debug ../
-
- true
- false
- true
-
-
- cmake
- -E chdir build/ cmake -G "MinGW Makefiles" -D CMAKE_BUILD_TYPE=Release ../
-
- true
- false
- true
-
-
- cmake
- -E chdir build/ cmake -G "Unix Makefiles" -D CMAKE_BUILD_TYPE=Debug ../
-
- true
- false
- true
-
-
- cmake
- -E chdir build/ cmake -G "Unix Makefiles" -D CMAKE_BUILD_TYPE=Release ../
-
- true
- false
- true
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- cmake
- -E chdir build/ cmake -G "MinGW Makefiles" -D CMAKE_BUILD_TYPE=Debug ../
-
- true
- false
- true
-
-
- cmake
- -E chdir build/ cmake -G "MinGW Makefiles" -D CMAKE_BUILD_TYPE=Release ../
-
- true
- false
- true
-
-
- cmake
- -E chdir build/ cmake -G "Unix Makefiles" -D CMAKE_BUILD_TYPE=Debug ../
-
- true
- false
- true
-
-
- cmake
- -E chdir build/ cmake -G "Unix Makefiles" -D CMAKE_BUILD_TYPE=Release ../
-
- true
- false
- true
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ cmake
+ -E chdir build/ cmake -G "MinGW Makefiles" -D CMAKE_BUILD_TYPE=Debug ../
+
+ true
+ false
+ true
+
+
+ cmake
+ -E chdir build/ cmake -G "MinGW Makefiles" -D CMAKE_BUILD_TYPE=Release ../
+
+ true
+ false
+ true
+
+
+ cmake
+ -E chdir build/ cmake -G "Unix Makefiles" -D CMAKE_BUILD_TYPE=Debug ../
+
+ true
+ false
+ true
+
+
+ cmake
+ -E chdir build/ cmake -G "Unix Makefiles" -D CMAKE_BUILD_TYPE=Release ../
+
+ true
+ false
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ cmake
+ -E chdir build/ cmake -G "MinGW Makefiles" -D CMAKE_BUILD_TYPE=Debug ../
+
+ true
+ false
+ true
+
+
+ cmake
+ -E chdir build/ cmake -G "MinGW Makefiles" -D CMAKE_BUILD_TYPE=Release ../
+
+ true
+ false
+ true
+
+
+ cmake
+ -E chdir build/ cmake -G "Unix Makefiles" -D CMAKE_BUILD_TYPE=Debug ../
+
+ true
+ false
+ true
+
+
+ cmake
+ -E chdir build/ cmake -G "Unix Makefiles" -D CMAKE_BUILD_TYPE=Release ../
+
+ true
+ false
+ true
+
+
+
+
+
+
+
+
+
+
+
+ cmake
+ -E chdir build/ cmake -G "MinGW Makefiles" -D CMAKE_BUILD_TYPE=Debug ../
+
+ true
+ false
+ true
+
+
+ cmake
+ -E chdir build/ cmake -G "MinGW Makefiles" -D CMAKE_BUILD_TYPE=Release ../
+
+ true
+ false
+ true
+
+
+ cmake
+ -E chdir build/ cmake -G "Unix Makefiles" -D CMAKE_BUILD_TYPE=Debug ../
+
+ true
+ false
+ true
+
+
+ cmake
+ -E chdir build/ cmake -G "Unix Makefiles" -D CMAKE_BUILD_TYPE=Release ../
+
+ true
+ false
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ea7fa34d..470d4377 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -41,7 +41,7 @@ SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib)
####### DEPENDENCIES #######
FIND_PACKAGE(OpenCV REQUIRED) # tested on 2.3.1
-FIND_PACKAGE(Qt4 COMPONENTS QtCore QtGui) # tested on Qt4.7
+FIND_PACKAGE(Qt4 COMPONENTS QtCore QtGui QtNetwork) # tested on Qt4.7
####### OSX BUNDLE CMAKE_INSTALL_PREFIX #######
OPTION(BUILD_AS_BUNDLE "Set to ON to build as bundle (DragNDrop)" OFF)
@@ -64,6 +64,7 @@ ENDIF(APPLE AND BUILD_AS_BUNDLE)
####### SOURCES (Projects) #######
ADD_SUBDIRECTORY( app )
ADD_SUBDIRECTORY( example )
+ADD_SUBDIRECTORY( tcpClient )
ADD_SUBDIRECTORY( console_app )
diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt
index 00c36575..323d1d1d 100644
--- a/app/CMakeLists.txt
+++ b/app/CMakeLists.txt
@@ -8,6 +8,7 @@ SET(headers_ui
../src/Camera.h
../src/ParametersToolBox.h
../src/AboutDialog.h
+ ../src/TcpServer.h
../src/utilite/UPlot.h
../src/rtabmap/PdfPlot.h
)
@@ -44,6 +45,7 @@ SET(SRC_FILES
../src/Settings.cpp
../src/ObjWidget.cpp
../src/AboutDialog.cpp
+ ../src/TcpServer.cpp
../src/utilite/UPlot.cpp
../src/utilite/UDirectory.cpp
../src/utilite/UFile.cpp
diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp
index 8311c05d..0d0eb776 100644
--- a/src/MainWindow.cpp
+++ b/src/MainWindow.cpp
@@ -12,6 +12,7 @@
#include "Settings.h"
#include "ParametersToolBox.h"
#include "AboutDialog.h"
+#include "TcpServer.h"
#include "rtabmap/PdfPlot.h"
#include
@@ -45,7 +46,8 @@ MainWindow::MainWindow(Camera * camera, const QString & settings, QWidget * pare
settings_(settings),
likelihoodCurve_(0),
lowestRefreshRate_(99),
- objectsModified_(false)
+ objectsModified_(false),
+ tcpServer_(0)
{
ui_ = new Ui_mainWindow();
ui_->setupUi(this);
@@ -88,7 +90,7 @@ MainWindow::MainWindow(Camera * camera, const QString & settings, QWidget * pare
ui_->menuView->addAction(ui_->dockWidget_parameters->toggleViewAction());
ui_->menuView->addAction(ui_->dockWidget_objects->toggleViewAction());
ui_->menuView->addAction(ui_->dockWidget_plot->toggleViewAction());
-connect(ui_->toolBox, SIGNAL(parametersChanged(const QStringList &)), this, SLOT(notifyParametersChanged(const QStringList &)));
+ connect(ui_->toolBox, SIGNAL(parametersChanged(const QStringList &)), this, SLOT(notifyParametersChanged(const QStringList &)));
ui_->imageView_source->setGraphicsViewMode(false);
ui_->imageView_source->setTextLabel(tr("Press \"space\" to start the camera..."));
@@ -152,6 +154,10 @@ connect(ui_->toolBox, SIGNAL(parametersChanged(const QStringList &)), this, SLOT
ui_->actionCamera_from_video_file->setChecked(!Settings::getCamera_5mediaPath().isEmpty() && !UDirectory::exists(Settings::getCamera_5mediaPath().toStdString()));
ui_->actionCamera_from_directory_of_images->setChecked(!Settings::getCamera_5mediaPath().isEmpty() && UDirectory::exists(Settings::getCamera_5mediaPath().toStdString()));
+ ui_->label_ipAddress->setTextInteractionFlags(Qt::TextSelectableByMouse);
+ ui_->label_port->setTextInteractionFlags(Qt::TextSelectableByMouse);
+ setupTCPServer();
+
if(Settings::getGeneral_autoStartCamera())
{
// Set 1 msec to see state on the status bar.
@@ -200,6 +206,21 @@ void MainWindow::closeEvent(QCloseEvent * event)
}
}
+void MainWindow::setupTCPServer()
+{
+ if(tcpServer_)
+ {
+ tcpServer_->close();
+ delete tcpServer_;
+ }
+ tcpServer_ = new TcpServer(Settings::getGeneral_port(), this);
+ connect(this, SIGNAL(objectsFound(QMultiMap >)), tcpServer_, SLOT(publishObjects(QMultiMap >)));
+ ui_->label_ipAddress->setText(tcpServer_->getHostAddress().toString());
+ ui_->label_port->setNum(tcpServer_->getPort());
+ printf("IP: %s\nport: %d\n",
+ tcpServer_->getHostAddress().toString().toStdString().c_str(), tcpServer_->getPort());
+}
+
ParametersToolBox * MainWindow::parametersToolBox() const
{
return ui_->toolBox;
@@ -1007,10 +1028,11 @@ protected:
++outliers_;
}
}
- if(Settings::getHomography_ignoreWhenAllInliers())
+
+ // ignore homography when all features are inliers
+ if(inliers_ == (int)outlierMask_.size() && !h_.empty())
{
- // ignore homography when all features are inliers
- if(inliers_ == (int)outlierMask_.size())
+ if(Settings::getHomography_ignoreWhenAllInliers() || cv::countNonZero(h_) < 1)
{
h_ = cv::Mat();
}
@@ -1506,6 +1528,13 @@ void MainWindow::notifyParametersChanged(const QStringList & paramChanged)
{
nearestNeighborParamsChanged = true;
}
+
+ if(iter->compare(Settings::kGeneral_port()) == 0 &&
+ Settings::getGeneral_port() != ui_->label_port->text().toInt() &&
+ Settings::getGeneral_port() != 0)
+ {
+ setupTCPServer();
+ }
}
if(Settings::getGeneral_autoUpdateObjects())
diff --git a/src/MainWindow.h b/src/MainWindow.h
index 69062b84..d36fab5d 100644
--- a/src/MainWindow.h
+++ b/src/MainWindow.h
@@ -22,6 +22,7 @@ class Camera;
class ParametersToolBox;
class QLabel;
class AboutDialog;
+class TcpServer;
namespace rtabmap
{
@@ -77,6 +78,7 @@ signals:
void objectsFound(const QMultiMap > &);
private:
+ void setupTCPServer();
void addObjectFromFile(const QString & filePath);
void showObject(ObjWidget * obj);
void updateData();
@@ -97,6 +99,7 @@ private:
int lowestRefreshRate_;
bool objectsModified_;
QMap imagesMap_;
+ TcpServer * tcpServer_;
};
#endif /* MainWindow_H_ */
diff --git a/src/ParametersToolBox.cpp b/src/ParametersToolBox.cpp
index 06efebee..32770033 100644
--- a/src/ParametersToolBox.cpp
+++ b/src/ParametersToolBox.cpp
@@ -423,7 +423,18 @@ void ParametersToolBox::changeParameter()
}
else if(spinBox)
{
- Settings::setParameter(sender()->objectName(), spinBox->value());
+ if(spinBox->objectName().compare(Settings::kHomography_minimumInliers()) == 0 &&
+ spinBox->value() < 4)
+ {
+ Settings::setHomography_minimumInliers(4);
+ spinBox->blockSignals(true);
+ this->updateParameter(Settings::kHomography_minimumInliers());
+ spinBox->blockSignals(false);
+ }
+ else
+ {
+ Settings::setParameter(sender()->objectName(), spinBox->value());
+ }
}
else if(lineEdit)
{
@@ -545,6 +556,7 @@ void ParametersToolBox::changeParameter(const int & value)
{
Settings::setParameter(sender()->objectName(), value==Qt::Checked?true:false);
}
+
paramChanged.append(sender()->objectName());
emit parametersChanged(paramChanged);
}
diff --git a/src/Settings.h b/src/Settings.h
index 9614c6d3..b136f3f0 100644
--- a/src/Settings.h
+++ b/src/Settings.h
@@ -175,11 +175,12 @@ class Settings
PARAMETER(General, threads, int, 1, "Number of threads used for objects matching and homography computation. 0 means as many threads as objects. On InvertedSearch mode, multi-threading has only effect on homography computation.");
PARAMETER(General, multiDetection, bool, false, "Multiple detection of the same object.");
PARAMETER(General, multiDetectionRadius, int, 30, "Ignore detection of the same object in X pixels radius of the previous detections.");
+ PARAMETER(General, port, int, 0, "Port on objects detected are published. If port=0, a port is chosen automatically.")
PARAMETER(Homography, homographyComputed, bool, true, "Compute homography? On ROS, this is required to publish objects detected.");
PARAMETER(Homography, method, QString, "1:LMEDS;RANSAC", "Type of the robust estimation algorithm: least-median algorithm or RANSAC algorithm.");
PARAMETER(Homography, ransacReprojThr, double, 1.0, "Maximum allowed reprojection error to treat a point pair as an inlier (used in the RANSAC method only). It usually makes sense to set this parameter somewhere in the range of 1 to 10.");
- PARAMETER(Homography, minimumInliers, int, 10, "Minimum inliers to accept the homography.");
+ PARAMETER(Homography, minimumInliers, int, 10, "Minimum inliers to accept the homography. Value must be >= 4.");
PARAMETER(Homography, ignoreWhenAllInliers, bool, false, "Ignore homography when all features are inliers (sometimes when the homography doesn't converge, it returns the best homography with all features as inliers).");
public:
diff --git a/src/TcpServer.cpp b/src/TcpServer.cpp
new file mode 100644
index 00000000..098d4373
--- /dev/null
+++ b/src/TcpServer.cpp
@@ -0,0 +1,99 @@
+/*
+ * TCPServer.cpp
+ *
+ * Created on: 2014-05-05
+ * Author: mathieu
+ */
+
+#include "TcpServer.h"
+
+#include
+#include
+#include
+
+TcpServer::TcpServer(quint16 port, QObject * parent) :
+ QTcpServer(parent)
+{
+ if (!this->listen(QHostAddress::Any, port))
+ {
+ printf("ERROR: Unable to start the TCP server: %s\n", this->errorString().toStdString().c_str());
+ return;
+ }
+
+ connect(this, SIGNAL(newConnection()), this, SLOT(addClient()));
+}
+
+QHostAddress TcpServer::getHostAddress() const
+{
+ QHostAddress hostAddress;
+
+ QList ipAddressesList = QNetworkInterface::allAddresses();
+ // use the first non-localhost IPv4 address
+ for (int i = 0; i < ipAddressesList.size(); ++i)
+ {
+ if (ipAddressesList.at(i) != QHostAddress::LocalHost && ipAddressesList.at(i).toIPv4Address())
+ {
+ hostAddress = ipAddressesList.at(i).toString();
+ break;
+ }
+ }
+
+ // if we did not find one, use IPv4 localhost
+ if (hostAddress.isNull())
+ {
+ hostAddress = QHostAddress(QHostAddress::LocalHost);
+ }
+
+ return hostAddress;
+}
+
+quint16 TcpServer::getPort() const
+{
+ return this->serverPort();
+}
+
+void TcpServer::publishObjects(const QMultiMap > & objects)
+{
+ if(objects.size())
+ {
+ QList clients = this->findChildren();
+ if(clients.size())
+ {
+ QVector data(objects.size()*12);
+ int i=0;
+ for(QMultiMap >::const_iterator iter=objects.constBegin(); iter!=objects.constEnd(); ++iter)
+ {
+ data[i++] = iter.key();
+ data[i++] = iter.value().first.width();
+ data[i++] = iter.value().first.height();
+ data[i++] = iter.value().second.m11();
+ data[i++] = iter.value().second.m12();
+ data[i++] = iter.value().second.m13();
+ data[i++] = iter.value().second.m21();
+ data[i++] = iter.value().second.m22();
+ data[i++] = iter.value().second.m23();
+ data[i++] = iter.value().second.m31(); // dx
+ data[i++] = iter.value().second.m32(); // dy
+ data[i++] = iter.value().second.m33();
+ }
+
+ for(QList::iterator iter = clients.begin(); iter!=clients.end(); ++iter)
+ {
+ QByteArray block;
+ QDataStream out(&block, QIODevice::WriteOnly);
+ out.setVersion(QDataStream::Qt_4_0);
+ out << (quint16)0;
+ out << data;
+ out.device()->seek(0);
+ out << (quint16)(block.size() - sizeof(quint16));
+ (*iter)->write(block);
+ }
+ }
+ }
+}
+
+void TcpServer::addClient()
+{
+ QTcpSocket * client = this->nextPendingConnection();
+ connect(client, SIGNAL(disconnected()), client, SLOT(deleteLater()));
+}
diff --git a/src/TcpServer.h b/src/TcpServer.h
new file mode 100644
index 00000000..487515ab
--- /dev/null
+++ b/src/TcpServer.h
@@ -0,0 +1,31 @@
+/*
+ * TCPServer.h
+ *
+ * Created on: 2014-05-05
+ * Author: mathieu
+ */
+
+#ifndef TCPSERVER_H_
+#define TCPSERVER_H_
+
+#include
+
+class QNetworkSession;
+
+class TcpServer : public QTcpServer
+{
+ Q_OBJECT
+
+public:
+ TcpServer(quint16 port = 0, QObject * parent = 0);
+
+ QHostAddress getHostAddress() const;
+ quint16 getPort() const;
+
+
+private slots:
+ void addClient();
+ void publishObjects(const QMultiMap > & objects);
+};
+
+#endif /* TCPSERVER_H_ */
diff --git a/src/ui/mainWindow.ui b/src/ui/mainWindow.ui
index 2345c749..d42ec29b 100644
--- a/src/ui/mainWindow.ui
+++ b/src/ui/mainWindow.ui
@@ -287,13 +287,20 @@
0
-
-
+
6
0
+
-
+
+
+ 000
+
+
+
-
@@ -420,13 +427,6 @@
- -
-
-
- 000
-
-
-
-
@@ -462,6 +462,34 @@
+ -
+
+
+ IP address
+
+
+
+ -
+
+
+ Port
+
+
+
+ -
+
+
+ 0.0.0.0
+
+
+
+ -
+
+
+ 0
+
+
+
@@ -478,7 +506,7 @@
0
0
360
- 120
+ 86
diff --git a/tcpClient/CMakeLists.txt b/tcpClient/CMakeLists.txt
new file mode 100644
index 00000000..13b4b801
--- /dev/null
+++ b/tcpClient/CMakeLists.txt
@@ -0,0 +1,37 @@
+### Qt Gui stuff ###
+SET(headers_ui
+ TcpClient.h
+)
+#This will generate moc_* for Qt
+QT4_WRAP_CPP(moc_srcs ${headers_ui})
+### Qt Gui stuff end###
+
+SET(SRC_FILES
+ TcpClient.cpp
+ main.cpp
+ ${moc_srcs}
+)
+
+SET(INCLUDE_DIRS
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${OpenCV_INCLUDE_DIRS}
+)
+
+INCLUDE(${QT_USE_FILE})
+
+SET(LIBRARIES
+ ${OpenCV_LIBS}
+ ${QT_LIBRARIES}
+)
+
+# Make sure the compiler can find include files from our library.
+INCLUDE_DIRECTORIES(${INCLUDE_DIRS})
+
+# Add binary called "example" that is built from the source file "main.cpp".
+# The extension is automatically found.
+ADD_EXECUTABLE(tcpClient ${SRC_FILES})
+TARGET_LINK_LIBRARIES(tcpClient ${LIBRARIES})
+
+SET_TARGET_PROPERTIES( tcpClient
+ PROPERTIES OUTPUT_NAME ${PROJECT_PREFIX}-tcpClient)
+
diff --git a/tcpClient/TcpClient.cpp b/tcpClient/TcpClient.cpp
new file mode 100644
index 00000000..dca0b4d4
--- /dev/null
+++ b/tcpClient/TcpClient.cpp
@@ -0,0 +1,132 @@
+/*
+ * TCPClient.cpp
+ *
+ * Created on: 2014-05-05
+ * Author: mathieu
+ */
+
+#include "TcpClient.h"
+
+#include
+#include
+#include
+
+TcpClient::TcpClient(const QString & hostname, quint16 port, QObject *parent) :
+ QTcpSocket(parent),
+ blockSize_(0)
+{
+ connect(this, SIGNAL(readyRead()), this, SLOT(readData()));
+ connect(this, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(displayError(QAbstractSocket::SocketError)));
+ connect(this, SIGNAL(disconnected()), this, SLOT(connectionLost()));
+
+ this->connectToHost(hostname, port);
+}
+
+void TcpClient::readData()
+{
+ QDataStream in(this);
+ in.setVersion(QDataStream::Qt_4_0);
+
+ if (blockSize_ == 0)
+ {
+ if (this->bytesAvailable() < (int)sizeof(quint16))
+ {
+ return;
+ }
+
+ in >> blockSize_;
+ }
+
+ if (this->bytesAvailable() < blockSize_)
+ {
+ return;
+ }
+
+ blockSize_ = 0;
+
+ QVector data;
+ in >> data;
+
+ printf("---\n");
+ for(int i=0; i(0,0) = data[i+3];
+ cvHomography.at(1,0) = data[i+4];
+ cvHomography.at(2,0) = data[i+5];
+ cvHomography.at(0,1) = data[i+6];
+ cvHomography.at(1,1) = data[i+7];
+ cvHomography.at(2,1) = data[i+8];
+ cvHomography.at(0,2) = data[i+9];
+ cvHomography.at(1,2) = data[i+10];
+ cvHomography.at(2,2) = data[i+11];
+ std::vector inPts, outPts;
+ inPts.push_back(cv::Point2f(0,0));
+ inPts.push_back(cv::Point2f(objectWidth,0));
+ inPts.push_back(cv::Point2f(0,objectHeight));
+ inPts.push_back(cv::Point2f(objectWidth,objectHeight));
+ cv::perspectiveTransform(inPts, outPts, cvHomography);
+
+ printf("Object %d detected, CV corners at (%f,%f) (%f,%f) (%f,%f) (%f,%f)\n",
+ id,
+ outPts.at(0).x, outPts.at(0).y,
+ outPts.at(1).x, outPts.at(1).y,
+ outPts.at(2).x, outPts.at(2).y,
+ outPts.at(3).x, outPts.at(3).y);
+ }
+ }
+}
+
+void TcpClient::displayError(QAbstractSocket::SocketError socketError)
+{
+ switch (socketError)
+ {
+ case QAbstractSocket::RemoteHostClosedError:
+ break;
+ case QAbstractSocket::HostNotFoundError:
+ printf("Tcp error: The host was not found. Please "
+ "check the host name and port settings.\n");
+ break;
+ case QAbstractSocket::ConnectionRefusedError:
+ printf("The connection was refused by the peer. "
+ "Make sure Find-Object is running, "
+ "and check that the host name and port "
+ "settings are correct.\n");
+ break;
+ default:
+ printf("The following error occurred: %s.\n", this->errorString().toStdString().c_str());
+ break;
+ }
+}
+
+void TcpClient::connectionLost()
+{
+ printf("Connection lost!\n");
+}
+
diff --git a/tcpClient/TcpClient.h b/tcpClient/TcpClient.h
new file mode 100644
index 00000000..87c2c3df
--- /dev/null
+++ b/tcpClient/TcpClient.h
@@ -0,0 +1,28 @@
+/*
+ * TCPClient.h
+ *
+ * Created on: 2014-05-05
+ * Author: mathieu
+ */
+
+#ifndef TCPCLIENT_H_
+#define TCPCLIENT_H_
+
+#include
+
+class TcpClient : public QTcpSocket
+{
+ Q_OBJECT;
+public:
+ TcpClient(const QString & hostname, quint16 port, QObject * parent = 0);
+
+private slots:
+ void readData();
+ void displayError(QAbstractSocket::SocketError socketError);
+ void connectionLost();
+
+private:
+ quint16 blockSize_;
+};
+
+#endif /* TCPCLIENT_H_ */
diff --git a/tcpClient/main.cpp b/tcpClient/main.cpp
new file mode 100644
index 00000000..14d97053
--- /dev/null
+++ b/tcpClient/main.cpp
@@ -0,0 +1,77 @@
+/*
+ * main.cpp
+ *
+ * Created on: 2014-05-05
+ * Author: mathieu
+ */
+
+#include
+#include
+#include "TcpClient.h"
+
+void showUsage()
+{
+ printf("exampleTcpClient [hostname] port\n");
+ exit(-1);
+}
+
+int main(int argc, char * argv[])
+{
+ if(argc < 2 || argc > 3)
+ {
+ showUsage();
+ }
+
+ QString ipAddress;
+ quint16 port = 0;
+
+ if(argc == 2)
+ {
+ port = std::atoi(argv[1]);
+ }
+ else if(argc == 3)
+ {
+ ipAddress = argv[1];
+ port = std::atoi(argv[2]);
+ }
+
+ if(ipAddress.isEmpty())
+ {
+ // find out which IP to connect to
+ QList ipAddressesList = QNetworkInterface::allAddresses();
+ // use the first non-localhost IPv4 address
+ for (int i = 0; i < ipAddressesList.size(); ++i)
+ {
+ if (ipAddressesList.at(i) != QHostAddress::LocalHost &&
+ ipAddressesList.at(i).toIPv4Address())
+ {
+ ipAddress = ipAddressesList.at(i).toString();
+ break;
+ }
+ }
+ // if we did not find one, use IPv4 localhost
+ if (ipAddress.isEmpty())
+ {
+ ipAddress = QHostAddress(QHostAddress::LocalHost).toString();
+ }
+ }
+
+ QCoreApplication app(argc, argv);
+
+ printf("Connecting to \"%s:%d\"...\n", ipAddress.toStdString().c_str(), port);
+
+ TcpClient client(ipAddress, port);
+
+ if(client.waitForConnected())
+ {
+ printf("Connecting to \"%s:%d\"... connected!\n", ipAddress.toStdString().c_str(), port);
+ app.exec();
+ }
+ else
+ {
+ printf("Connecting to \"%s:%d\"... connection failed!\n", ipAddress.toStdString().c_str(), port);
+ }
+
+ return 0;
+}
+