ATLAS Offline Software
VP1TcpServer.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 // //
7 // Implementation of class VP1TcpServer //
8 // //
9 // Author: Thomas Kittelmann <Thomas.Kittelmann@cern.ch> //
10 // //
11 // Initial version: April 2007 //
12 // //
14 
15 #include "VP1Gui/VP1TcpServer.h"
16 #include <QTcpServer>
17 #include <QTcpSocket>
18 #include <QDataStream>
19 #include <QTimer>
20 #include <QMap>
21 #include <cassert>
22 
23 //____________________________________________________________________
25 public:
27  quint16 port;
28  QTcpServer tcpserver;
29  QMap<QTcpSocket *,quint16> sockets2blocksize;
30  QTcpSocket * recognisedSocket(QObject*) const;
32 };
33 
34 //____________________________________________________________________
36  : QObject(), m_d(new Imp)
37 {
38  m_d->lastemit_listen=-1;
39  m_d->tcpserv=this;
40  m_d->port=0;
41  connect(&m_d->tcpserver, SIGNAL(newConnection()),this, SLOT(acceptConnection()));
42 
43  //
44  QTimer * timer = new QTimer(this);
45  timer->start(2000);
46  connect(timer, SIGNAL(timeout()),this, SLOT(listenStateMightHaveChanged()));
47 }
48 
49 //____________________________________________________________________
51 {
52  close();
53  delete m_d; m_d=0;
54 }
55 
56 //____________________________________________________________________
57 bool VP1TcpServer::listen(QString& err, const quint16& port) {
58  if (isListening())
59  close();
60  bool success = m_d->tcpserver.listen(QHostAddress::LocalHost,port);
61  if (!success) {
62  err = m_d->tcpserver.errorString();
63  m_d->port=0;
65  return false;
66  }
67  m_d->port=port;
68  err.clear();
69 
71  return true;
72 }
73 
74 //____________________________________________________________________
75 quint16 VP1TcpServer::port() const
76 {
77  return m_d->port;
78 }
79 
80 //____________________________________________________________________
82 {
83  return m_d->tcpserver.isListening();
84 }
85 
86 //____________________________________________________________________
88 {
89  if (!isListening())
90  return;
91  disconnect(&m_d->tcpserver, SIGNAL(newConnection()),this, SLOT(acceptConnection()));
92 
93  QMapIterator<QTcpSocket *,quint16> it(m_d->sockets2blocksize);
94  while (it.hasNext()) {
95  it.next();
96  QTcpSocket * socket = it.key();
97  delete socket;
98  }
99  m_d->sockets2blocksize.clear();
100 
101  m_d->tcpserver.close();
102  m_d->port=0;
104 }
105 
106 //____________________________________________________________________
108 {
109  if (!m_d->tcpserver.hasPendingConnections())
110  return;
111  QTcpSocket * socket = m_d->tcpserver.nextPendingConnection();
112  if (m_d->sockets2blocksize.contains(socket)) {
113  //we are already dealing with this one, but look back here in a
114  //short while to se if anything else is queued.
115  QTimer::singleShot(100, this, SLOT(acceptConnection()));
116  return;
117  }
118  assert(!m_d->sockets2blocksize.contains(socket));
119  m_d->sockets2blocksize.insert(socket,0);
120  connect(socket, SIGNAL(readyRead()),this, SLOT(readData()));
121  connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(handleError(QAbstractSocket::SocketError)));
122  connect(socket, SIGNAL(disconnected()),socket, SLOT(deleteLater()));
123  connect(socket, SIGNAL(destroyed(QObject*)),this,SLOT(socketDestroyed (QObject*)));
125 }
126 
127 //____________________________________________________________________
128 void VP1TcpServer::handleError(QAbstractSocket::SocketError se)
129 {
130  if (se == QTcpSocket::RemoteHostClosedError)
131  return;
132  QTcpSocket * socket = m_d->recognisedSocket(sender());
133  if (!socket)
134  return;
135  if (socket->state()!=QAbstractSocket::UnconnectedState) {
136  socket->disconnectFromHost();
137  }
138  // std::cout << "VP1TcpServer::Error during connection:"<<m_d->tcpserver.errorString().toStdString()<<std::endl;
140 }
141 
142 //____________________________________________________________________
144 {
145  QTcpSocket * socket = m_d->recognisedSocket(sender());
146  if (!socket)
147  return;
148  if (socket->state()!=QAbstractSocket::ConnectedState) {
149  // assert(0&&"This should never happen...");
150  return;
151  }
152 
153  QDataStream in(socket);
154  in.setVersion(QDataStream::Qt_4_2);
155 
156  //Make sure that we can read enough to determine the data length:
157  if (m_d->sockets2blocksize[socket] == 0) {
158  if (socket->bytesAvailable() < (int)sizeof(quint16))
159  return;
160  in >> m_d->sockets2blocksize[socket];
161  }
162 
163  //Make sure that we can read all of the data:
164  if (socket->bytesAvailable() < m_d->sockets2blocksize[socket])
165  return;
166 
167  QString data;
168  in >> data;
169  // qDebug(QString("Got: "+data).toStdString().c_str());
170 
171  if (m_d->sockets2blocksize.contains(socket)) {
172  socket->disconnectFromHost();
173  }
174 
175  //Notice that we dont fire any signals unless we positively see something that we know how to handle!
176  if (data.startsWith("VP1ExternalRequest")) {
177  VP1ExternalRequest request(data);
178  if (request.isValid()) {
179  //qDebug("Got valid VP1ExternalRequest!");
180  receivedExternalRequest(request);
181  }
182  }
184 }
185 
186 //____________________________________________________________________
187 QTcpSocket * VP1TcpServer::Imp::recognisedSocket(QObject*o) const
188 {
189  QTcpSocket * socket = static_cast<QTcpSocket *>(o);
190  if (!socket)
191  return 0;
192  return sockets2blocksize.contains(socket) ? socket : 0;
193 }
194 
195 //____________________________________________________________________
197 {
198  QTcpSocket * socket = static_cast<QTcpSocket *>(obj);
199  if (!socket)
200  return;
201  if (m_d->sockets2blocksize.contains(socket))
202  m_d->sockets2blocksize.remove(socket);
204 }
205 //____________________________________________________________________
207 {
208  bool l = isListening();
209  bool last = m_d->lastemit_listen == 1 ? true : false;
210  if (m_d->lastemit_listen==-1||(l!=last)) {
212  }
213  m_d->lastemit_listen = l ? 1 : 0;
214 }
data
char data[hepevt_bytes_allocation_ATLAS]
Definition: HepEvt.cxx:11
VP1TcpServer
Definition: VP1TcpServer.h:22
VP1TcpServer.h
VP1TcpServer::Imp::lastemit_listen
int lastemit_listen
Definition: VP1TcpServer.cxx:31
fillPileUpNoiseLumi.connect
string connect
Definition: fillPileUpNoiseLumi.py:70
CSV_InDetExporter.new
new
Definition: CSV_InDetExporter.py:145
VP1TcpServer::listen
bool listen(QString &err, const quint16 &port=4747)
Definition: VP1TcpServer.cxx:57
VP1TcpServer::Imp::sockets2blocksize
QMap< QTcpSocket *, quint16 > sockets2blocksize
Definition: VP1TcpServer.cxx:29
skel.it
it
Definition: skel.GENtoEVGEN.py:423
VP1TcpServer::readData
void readData()
Definition: VP1TcpServer.cxx:143
UploadAMITag.l
list l
Definition: UploadAMITag.larcaf.py:158
VP1TcpServer::~VP1TcpServer
virtual ~VP1TcpServer()
Definition: VP1TcpServer.cxx:50
keylayer_zslicemap.se
se
Definition: keylayer_zslicemap.py:194
python.utils.AtlRunQueryTimer.timer
def timer(name, disabled=False)
Definition: AtlRunQueryTimer.py:86
dqt_zlumi_pandas.err
err
Definition: dqt_zlumi_pandas.py:193
VP1TcpServer::receivedExternalRequest
void receivedExternalRequest(VP1ExternalRequest)
VP1TcpServer::port
quint16 port() const
Definition: VP1TcpServer.cxx:75
VP1ExternalRequest
Definition: VP1ExternalRequest.h:20
VP1TcpServer::close
void close()
Definition: VP1TcpServer.cxx:87
VP1TcpServer::m_d
Imp * m_d
Definition: VP1TcpServer.h:50
VP1TcpServer::VP1TcpServer
VP1TcpServer()
Definition: VP1TcpServer.cxx:35
VP1TcpServer::Imp::tcpserver
QTcpServer tcpserver
Definition: VP1TcpServer.cxx:28
VP1TcpServer::acceptConnection
void acceptConnection()
Definition: VP1TcpServer.cxx:107
VP1TcpServer::listenStateChanged
void listenStateChanged(bool)
VP1TcpServer::Imp::tcpserv
VP1TcpServer * tcpserv
Definition: VP1TcpServer.cxx:26
VP1TcpServer::socketDestroyed
void socketDestroyed(QObject *)
Definition: VP1TcpServer.cxx:196
VP1TcpServer::listenStateMightHaveChanged
void listenStateMightHaveChanged()
Definition: VP1TcpServer.cxx:206
VP1TcpServer::handleError
void handleError(QAbstractSocket::SocketError)
Definition: VP1TcpServer.cxx:128
VP1ExternalRequest::isValid
bool isValid() const
Definition: VP1ExternalRequest.h:29
VP1TcpServer::Imp::port
quint16 port
Definition: VP1TcpServer.cxx:27
VP1TcpServer::Imp
Definition: VP1TcpServer.cxx:24
get_generator_info.error
error
Definition: get_generator_info.py:40
python.PyAthena.obj
obj
Definition: PyAthena.py:135
python.TrigInDetArtSteps.timeout
timeout
Definition: TrigInDetArtSteps.py:35
VP1TcpServer::isListening
bool isListening()
Definition: VP1TcpServer.cxx:81
VP1TcpServer::Imp::recognisedSocket
QTcpSocket * recognisedSocket(QObject *) const
Definition: VP1TcpServer.cxx:187