ATLAS Offline Software
Loading...
Searching...
No Matches
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//____________________________________________________________________
25public:
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//____________________________________________________________________
57bool 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//____________________________________________________________________
75quint16 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//____________________________________________________________________
128void 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!");
181 }
182 }
184}
185
186//____________________________________________________________________
187QTcpSocket * 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//____________________________________________________________________
196void VP1TcpServer::socketDestroyed ( QObject * obj )
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}
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
VP1TcpServer * tcpserv
QTcpSocket * recognisedSocket(QObject *) const
QMap< QTcpSocket *, quint16 > sockets2blocksize
void socketDestroyed(QObject *)
void listenStateChanged(bool)
void acceptConnection()
void handleError(QAbstractSocket::SocketError)
void receivedExternalRequest(VP1ExternalRequest)
quint16 port() const
bool listen(QString &err, const quint16 &port=4747)
void listenStateMightHaveChanged()
virtual ~VP1TcpServer()