CustusX  16.5.0-rc9
An IGT application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
cxSocket.cpp
Go to the documentation of this file.
1 /*=========================================================================
2 This file is part of CustusX, an Image Guided Therapy Application.
3 
4 Copyright (c) 2008-2014, SINTEF Department of Medical Technology
5 All rights reserved.
6 
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
9 
10 1. Redistributions of source code must retain the above copyright notice,
11  this list of conditions and the following disclaimer.
12 
13 2. Redistributions in binary form must reproduce the above copyright notice,
14  this list of conditions and the following disclaimer in the documentation
15  and/or other materials provided with the distribution.
16 
17 3. Neither the name of the copyright holder nor the names of its contributors
18  may be used to endorse or promote products derived from this software
19  without specific prior written permission.
20 
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 =========================================================================*/
32 
33 
34 #include "cxSocket.h"
35 
36 #include <QTcpSocket>
37 #include "cxLogger.h"
38 #include <QTcpServer>
39 #include <QNetworkInterface>
40 
41 namespace cx
42 {
43 
44 //void SingleConnectionTcpServer::setSocket(QPointer<Socket> socket)
45 //{
46 // mSocket = socket;
47 //}
48 
50  QTcpServer(parent)
51 {
52 }
53 
54 
55 void SingleConnectionTcpServer::incomingConnection(qintptr socketDescriptor)
56 {
57  emit incoming(socketDescriptor);
58 }
59 
60 //---------------------------------------------------------
61 //---------------------------------------------------------
62 //---------------------------------------------------------
63 
65  mInfo(info),
66  mSocket(socket)
67 {
68  connect(mSocket, &QTcpSocket::connected, this, &SocketClientConnector::internalConnected);
69  connect(mSocket, &QTcpSocket::disconnected, this, &SocketClientConnector::internalDisconnected);
70 }
71 
73 {
74 
75 }
76 
78 {
79  CX_LOG_INFO() << "Trying to connect to " << mInfo.getDescription();
81  mSocket->connectToHost(mInfo.host, mInfo.port);
82 }
83 
85 {
86  mSocket->close();
87 // this->stopListen();
88 }
89 
91 {
92  if (mSocket->state() == QAbstractSocket::ConnectedState)
93  return scsCONNECTED;
94  if (mSocket->state() == QAbstractSocket::UnconnectedState)
95  return scsINACTIVE;
96  return scsCONNECTING;
97 }
98 
99 void SocketClientConnector::internalConnected()
100 {
101  CX_LOG_SUCCESS() << "Connected to " << mInfo.getDescription();
102  emit stateChanged(this->getState());
103 }
104 
105 void SocketClientConnector::internalDisconnected()
106 {
107  CX_LOG_SUCCESS() << "Disconnected";
108  this->stateChanged(this->getState());
109 }
110 
111 
112 //---------------------------------------------------------
113 //---------------------------------------------------------
114 //---------------------------------------------------------
115 
117  mInfo(info),
118  mSocket(socket)
119 {
120 
121 }
122 
124 {
125 
126 }
127 
129 {
130  this->startListen();
131 }
132 
134 {
135  this->stopListen();
136 }
137 
139 {
140  if (mSocket->state() == QAbstractSocket::ConnectedState)
141  return scsCONNECTED;
142  if (mServer->isListening())
143  return scsLISTENING;
144  if (mSocket->state() == QAbstractSocket::UnconnectedState)
145  return scsINACTIVE;
146  return scsCONNECTING;
147 }
148 
149 bool SocketServerConnector::startListen()
150 {
151  if (!mServer)
152  {
153  mServer = new SingleConnectionTcpServer(this);
154  connect(mServer.data(), &SingleConnectionTcpServer::incoming, this, &SocketServerConnector::incomingConnection);
155 // mServer->setSocket(mSocket);
156  }
158 
159  bool started = mServer->listen(QHostAddress::Any, mInfo.port);
160 
161  if (started)
162  {
163  CX_LOG_INFO() << QString("Server address: %1").arg(this->getAllServerHostnames().join(", "));
164  CX_LOG_INFO() << QString("Server is listening to port %1").arg(mServer->serverPort());
165  }
166  else
167  {
168  CX_LOG_INFO() << QString("Server failed to start. Error: %1").arg(mServer->errorString());
169  }
170 
171  emit stateChanged(this->getState());
172  return started;
173 }
174 
175 void SocketServerConnector::stopListen()
176 {
177  mSocket->close();
178 
179  if (mServer && mServer->isListening())
180  {
181  CX_LOG_INFO() << QString("Server stopped listening to port %1").arg(mServer->serverPort());
182  mServer->close();
183  emit stateChanged(this->getState());
184  }
185 }
186 
187 void SocketServerConnector::incomingConnection(qintptr socketDescriptor)
188 {
189  CX_LOG_INFO() << "Server: Incoming connection...";
190 
191  if (this->mSocket->state() == QAbstractSocket::ConnectedState)
192  {
193  reportError("Incoming connection request rejected: The server can only handle a single connection.");
194  return;
195  }
196 
197  int success = mSocket->setSocketDescriptor(socketDescriptor, QAbstractSocket::ConnectedState);
198  QString clientName = mSocket->localAddress().toString();
199  report("Connected to "+clientName+". Session started." + qstring_cast(success));
200 
201  emit stateChanged(this->getState());
202 }
203 
204 QStringList SocketServerConnector::getAllServerHostnames()
205 {
206  QStringList addresses;
207 
208  foreach(QNetworkInterface interface, QNetworkInterface::allInterfaces())
209  {
210  if (interface.flags().testFlag(QNetworkInterface::IsRunning))
211  foreach (QNetworkAddressEntry entry, interface.addressEntries())
212  {
213  if ( interface.hardwareAddress() != "00:00:00:00:00:00"
214  && entry.ip().toString() != "127.0.0.1"
215  && entry.ip().toString().contains(".") )
216  addresses << QString("%1: %2").arg(interface.name()).arg(entry.ip().toString());
217  }
218  }
219 
220  return addresses;
221 }
222 
223 
224 
225 }//namespace cx
QString qstring_cast(const T &val)
void incoming(qintptr socketDescriptor)
CX_SOCKETCONNECTION_STATE
virtual ~SocketClientConnector()
Definition: cxSocket.cpp:72
void reportError(QString msg)
Definition: cxLogger.cpp:92
SingleConnectionTcpServer(QObject *parent)
Definition: cxSocket.cpp:49
#define CX_LOG_INFO
Definition: cxLogger.h:111
virtual void activate()
Definition: cxSocket.cpp:77
SocketServerConnector(SocketConnection::ConnectionInfo info, QTcpSocket *socket)
Definition: cxSocket.cpp:116
virtual ~SocketServerConnector()
Definition: cxSocket.cpp:123
void incomingConnection(qintptr socketDescriptor)
Definition: cxSocket.cpp:55
#define CX_LOG_SUCCESS
Definition: cxLogger.h:112
virtual CX_SOCKETCONNECTION_STATE getState()
Definition: cxSocket.cpp:90
void stateChanged(CX_SOCKETCONNECTION_STATE)
void report(QString msg)
Definition: cxLogger.cpp:90
SocketClientConnector(SocketConnection::ConnectionInfo info, QTcpSocket *socket)
Definition: cxSocket.cpp:64
virtual CX_SOCKETCONNECTION_STATE getState()
Definition: cxSocket.cpp:138
virtual void deactivate()
Definition: cxSocket.cpp:133
virtual void deactivate()
Definition: cxSocket.cpp:84
virtual void activate()
Definition: cxSocket.cpp:128