TcpServer.cpp
Go to the documentation of this file.
1 /*
2 Copyright (c) 2011-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
3 All rights reserved.
4 
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7  * Redistributions of source code must retain the above copyright
8  notice, this list of conditions and the following disclaimer.
9  * Redistributions in binary form must reproduce the above copyright
10  notice, this list of conditions and the following disclaimer in the
11  documentation and/or other materials provided with the distribution.
12  * Neither the name of the Universite de Sherbrooke nor the
13  names of its contributors may be used to endorse or promote products
14  derived from this software without specific prior written permission.
15 
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27 #include "find_object/TcpServer.h"
29 
30 #include <QtNetwork/QNetworkInterface>
31 #include <QtNetwork/QTcpSocket>
32 #include <QtGui/QTransform>
33 #include <opencv2/highgui/highgui.hpp>
34 
35 namespace find_object {
36 
37 TcpServer::TcpServer(quint16 port, QObject * parent) :
38  QTcpServer(parent)
39 {
40  if (!this->listen(QHostAddress::Any, port))
41  {
42  UERROR("Unable to start the TCP server: %s", this->errorString().toStdString().c_str());
43  return;
44  }
45 
46  connect(this, SIGNAL(newConnection()), this, SLOT(addClient()));
47 }
48 
49 QHostAddress TcpServer::getHostAddress() const
50 {
51  QHostAddress hostAddress;
52 
53  QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();
54  // use the first non-localhost IPv4 address
55  for (int i = 0; i < ipAddressesList.size(); ++i)
56  {
57  if (ipAddressesList.at(i) != QHostAddress::LocalHost && ipAddressesList.at(i).toIPv4Address())
58  {
59  hostAddress = ipAddressesList.at(i).toString();
60  break;
61  }
62  }
63 
64  // if we did not find one, use IPv4 localhost
65  if (hostAddress.isNull())
66  {
67  hostAddress = QHostAddress(QHostAddress::LocalHost);
68  }
69 
70  return hostAddress;
71 }
72 
73 quint16 TcpServer::getPort() const
74 {
75  return this->serverPort();
76 }
77 
79 {
80  QList<QTcpSocket*> clients = this->findChildren<QTcpSocket*>();
81  if(clients.size())
82  {
83  UINFO("TCP server: Publish detected objects");
84  QByteArray block;
85  QDataStream out(&block, QIODevice::WriteOnly);
86  out.setVersion(QDataStream::Qt_4_0);
87  out << (quint16)0;
88 
89  out << info;
90 
91  out.device()->seek(0);
92  out << (quint16)(block.size() - sizeof(quint16));
93 
94  for(QList<QTcpSocket*>::iterator iter = clients.begin(); iter!=clients.end(); ++iter)
95  {
96  (*iter)->write(block);
97  }
98  }
99 }
100 
102 {
103  while(this->hasPendingConnections())
104  {
105  QTcpSocket * client = this->nextPendingConnection();
106  connect(client, SIGNAL(readyRead()), this, SLOT(readReceivedData()));
107  connect(client, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(displayError(QAbstractSocket::SocketError)));
108  connect(client, SIGNAL(disconnected()), this, SLOT(connectionLost()));
109  }
110 }
111 
113 {
114  QTcpSocket * client = (QTcpSocket*)sender();
115  QDataStream in(client);
116  in.setVersion(QDataStream::Qt_4_0);
117 
118  if (blockSizes_.value(client->socketDescriptor(), 0) == 0)
119  {
120  if (client->bytesAvailable() < (int)sizeof(quint64))
121  {
122  return;
123  }
124 
125  in >> blockSizes_[client->socketDescriptor()];
126  }
127 
128  if (client->bytesAvailable() < (int)blockSizes_[client->socketDescriptor()])
129  {
130  return;
131  }
132 
133  quint32 serviceType;
134  in >> serviceType;
135 
136  bool ok = true;
137  if(serviceType == kAddObject)
138  {
139  int id;
140  in >> id;
141  QString fileName;
142  in >> fileName;
143  quint64 imageSize;
144  in >> imageSize;
145  std::vector<unsigned char> buf(imageSize);
146  in.readRawData((char*)buf.data(), imageSize);
147  cv::Mat image = cv::imdecode(buf, cv::IMREAD_UNCHANGED);
148 
149  UINFO("TCP service: Add %d \"%s\"", id, fileName.toStdString().c_str());
150  Q_EMIT addObject(image, id, fileName);
151  }
152  else if(serviceType == kRemoveObject)
153  {
154  int id;
155  in >> id;
156 
157  UINFO("TCP service: Remove %d", id);
158  Q_EMIT removeObject(id);
159  }
160  else if(serviceType == kDetectObject)
161  {
162  std::vector<unsigned char> buf(blockSizes_[client->socketDescriptor()]);
163  in.readRawData((char*)buf.data(), blockSizes_[client->socketDescriptor()]-sizeof(quint32));
164  cv::Mat image = cv::imdecode(buf, cv::IMREAD_UNCHANGED);
165 
166  UINFO("TCP service: Detect object");
167  Q_EMIT detectObject(image);
168  }
169  else
170  {
171  UERROR("Unknown service type called %d", serviceType);
172  ok = false;
173  }
174 
175  blockSizes_.remove(client->socketDescriptor());
176  client->write(QByteArray(ok?"1":"0")); // send acknowledge
177 }
178 
179 void TcpServer::displayError(QAbstractSocket::SocketError socketError)
180 {
181  switch (socketError)
182  {
183  case QAbstractSocket::RemoteHostClosedError:
184  break;
185  case QAbstractSocket::HostNotFoundError:
186  UWARN("CameraTcp: Tcp error: The host was not found. Please "
187  "check the host name and port settings.\n");
188  break;
189  case QAbstractSocket::ConnectionRefusedError:
190  UWARN("CameraTcp: The connection was refused by the peer. "
191  "Make sure your images server is running, "
192  "and check that the host name and port "
193  "settings are correct.");
194  break;
195  default:
196  //UERROR("The following error occurred: %s.", this->errorString().toStdString().c_str());
197  break;
198  }
199 }
200 
202 {
203  //printf("[WARNING] CameraTcp: Connection lost!\n");
204  blockSizes_.remove(((QTcpSocket*)sender())->socketDescriptor());
205  ((QTcpSocket*)sender())->close();
206  sender()->deleteLater();
207 }
208 
209 } // namespace find_object
quint16 getPort() const
Definition: TcpServer.cpp:73
TcpServer(quint16 port=0, QObject *parent=0)
Definition: TcpServer.cpp:37
void displayError(QAbstractSocket::SocketError socketError)
Definition: TcpServer.cpp:179
QHostAddress getHostAddress() const
Definition: TcpServer.cpp:49
void detectObject(const cv::Mat &)
static bool in(Reader::Char c, Reader::Char c1, Reader::Char c2, Reader::Char c3, Reader::Char c4)
Definition: jsoncpp.cpp:244
void addObject(const cv::Mat &, int, const QString &)
#define UERROR(...)
ULogger class and convenient macros.
#define UWARN(...)
QMap< int, quint64 > blockSizes_
Definition: TcpServer.h:74
void publishDetectionInfo(const find_object::DetectionInfo &info)
Definition: TcpServer.cpp:78
#define UINFO(...)


find_object_2d
Author(s): Mathieu Labbe
autogenerated on Thu Jun 6 2019 19:22:26