CameraTcpServer.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/Settings.h"
29 
30 #include "CameraTcpServer.h"
31 #include <QtNetwork/QTcpSocket>
32 #include <QtNetwork/QNetworkInterface>
33 #include <QtCore/QDataStream>
34 
35 namespace find_object {
36 
37 CameraTcpServer::CameraTcpServer(quint16 port, QObject *parent) :
38  QTcpServer(parent),
39  blockSize_(0)
40 {
41  if (!this->listen(QHostAddress::Any, port))
42  {
43  UERROR("Unable to start the Camera TCP server: %s", this->errorString().toStdString().c_str());
44  return;
45  }
46 }
47 
49 {
50  cv::Mat img;
51  if(images_.size())
52  {
53  // if queue changed after tcp connection ended with images still in the buffer
54  int queue = Settings::getCamera_9queueSize();
55  while(queue > 0 && images_.size() > queue)
56  {
57  images_.pop_front();
58  }
59 
60  img = images_.front();
61  images_.pop_front();
62  }
63  if(this->findChildren<QTcpSocket*>().size() == 1)
64  {
65  this->findChildren<QTcpSocket*>().first()->waitForReadyRead(100);
66  }
67  return img;
68 }
69 
71 {
72  return this->findChildren<QTcpSocket*>().size() > 0;
73 }
74 
75 QHostAddress CameraTcpServer::getHostAddress() const
76 {
77  QHostAddress hostAddress;
78 
79  QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();
80  // use the first non-localhost IPv4 address
81  for (int i = 0; i < ipAddressesList.size(); ++i)
82  {
83  if (ipAddressesList.at(i) != QHostAddress::LocalHost && ipAddressesList.at(i).toIPv4Address())
84  {
85  hostAddress = ipAddressesList.at(i).toString();
86  break;
87  }
88  }
89 
90  // if we did not find one, use IPv4 localhost
91  if (hostAddress.isNull())
92  {
93  hostAddress = QHostAddress(QHostAddress::LocalHost);
94  }
95 
96  return hostAddress;
97 }
98 
99 quint16 CameraTcpServer::getPort() const
100 {
101  return this->serverPort();
102 }
103 #if QT_VERSION >= 0x050000
104 void CameraTcpServer::incomingConnection(qintptr socketDescriptor)
105 #else
106 void CameraTcpServer::incomingConnection(int socketDescriptor)
107 #endif
108 {
109  QList<QTcpSocket*> clients = this->findChildren<QTcpSocket*>();
110  if(clients.size() >= 1)
111  {
112  UWARN("A client is already connected. Only one connection allowed at the same time.");
113  QTcpSocket socket;
114  socket.setSocketDescriptor(socketDescriptor);
115  socket.close(); // close without sending an acknowledge
116  }
117  else
118  {
119  QTcpSocket * socket = new QTcpSocket(this);
120  connect(socket, SIGNAL(readyRead()), this, SLOT(readReceivedData()));
121  connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(displayError(QAbstractSocket::SocketError)));
122  connect(socket, SIGNAL(disconnected()), this, SLOT(connectionLost()));
123  socket->setSocketDescriptor(socketDescriptor);
124  socket->write(QByteArray("1")); // send acknowledge
125  }
126 }
127 
129 {
130  QTcpSocket * client = (QTcpSocket*)sender();
131  QDataStream in(client);
132  in.setVersion(QDataStream::Qt_4_0);
133 
134  if (blockSize_ == 0)
135  {
136  if (client->bytesAvailable() < (int)sizeof(quint64))
137  {
138  return;
139  }
140 
141  in >> blockSize_;
142  }
143 
144  if (client->bytesAvailable() < (int)blockSize_)
145  {
146  return;
147  }
148 
149  std::vector<unsigned char> buf(blockSize_);
150  in.readRawData((char*)buf.data(), blockSize_);
151  images_.push_back(cv::imdecode(buf, cv::IMREAD_UNCHANGED));
152  int queue = Settings::getCamera_9queueSize();
153  while(queue > 0 && images_.size() > queue)
154  {
155  images_.pop_front();
156  }
157  blockSize_ = 0;
158 }
159 
160 void CameraTcpServer::displayError(QAbstractSocket::SocketError socketError)
161 {
162  switch (socketError)
163  {
164  case QAbstractSocket::RemoteHostClosedError:
165  break;
166  case QAbstractSocket::HostNotFoundError:
167  UWARN("CameraTcp: Tcp error: The host was not found. Please "
168  "check the host name and port settings.\n");
169  break;
170  case QAbstractSocket::ConnectionRefusedError:
171  UWARN("CameraTcp: The connection was refused by the peer. "
172  "Make sure your images server is running, "
173  "and check that the host name and port "
174  "settings are correct.");
175  break;
176  default:
177  //UERROR("The following error occurred: %s.", this->errorString().toStdString().c_str());
178  break;
179  }
180 }
181 
183 {
184  //printf("[WARNING] CameraTcp: Connection lost!\n");
185  ((QTcpSocket*)sender())->close();
186  sender()->deleteLater();
187  blockSize_ = 0; // reset
188 }
189 
190 } // namespace find_object
QHostAddress getHostAddress() const
QVector< cv::Mat > images_
virtual void incomingConnection(int socketDescriptor)
void displayError(QAbstractSocket::SocketError socketError)
static bool in(Reader::Char c, Reader::Char c1, Reader::Char c2, Reader::Char c3, Reader::Char c4)
Definition: jsoncpp.cpp:244
CameraTcpServer(quint16 port=0, QObject *parent=0)
#define UERROR(...)
ULogger class and convenient macros.
#define UWARN(...)


find_object_2d
Author(s): Mathieu Labbe
autogenerated on Mon Dec 12 2022 03:20:09