KDEGames

kmessageio.h
1 /*
2  This file is part of the KDE games library
3  SPDX-FileCopyrightText: 2001 Burkhard Lehner <[email protected]>
4 
5  SPDX-License-Identifier: LGPL-2.0-only
6 */
7 
8 /*
9  KMessageIO class and subclasses KMessageSocket and KMessageDirect
10 */
11 
12 #ifndef _KMESSAGEIO_H_
13 #define _KMESSAGEIO_H_
14 
15 // own
16 #include "libkdegamesprivate_export.h"
17 // Qt
18 #include <QObject>
19 #include <QProcess>
20 #include <QString>
21 #include <QHostAddress>
22 #include <QLoggingCategory>
23 
24 /*
25  This macro shouldn't be here ideally. Already declared in kgame.h, but throws error if not placed here.
26 */
27 Q_DECLARE_LOGGING_CATEGORY(GAMES_PRIVATE_KGAME)
28 
29 class QTcpSocket;
30 class KProcess;
31 
32 
33 /**
34  \class KMessageIO kmessageio.h <KGame/KMessageIO>
35 
36  This abstract base class represents one end of a message connections
37  between two clients. Each client has one object of a subclass of
38  KMessageIO. Calling /e send() on one object will emit the signal
39  /e received() on the other object, and vice versa.
40 
41  For each type of connection (TCP/IP socket, COM port, direct connection
42  within the same class) a subclass of KMessageIO must be defined that
43  implements the pure virtual methods /e send() and /e isConnected(),
44  and sends the signals. (See /e KMessageSocket for an example implementation.)
45 
46  Two subclasses are already included: /e KMessageSocket (connection using
47  TCP/IP sockets) and /e KMessageDirect (connection using method calls, both
48  sides must be within the same process).
49 */
50 
51 class KDEGAMESPRIVATE_EXPORT KMessageIO : public QObject
52 {
53  Q_OBJECT
54 
55 public:
56  /**
57  * The usual QObject constructor, does nothing else.
58  **/
59  explicit KMessageIO (QObject *parent = nullptr);
60 
61  /**
62  * The usual destructor, does nothing special.
63  **/
64  ~KMessageIO () override;
65 
66  /**
67  * The runtime identification
68  */
69  virtual int rtti() const {return 0;}
70 
71  /**
72  * @return Whether this KMessageIO is a network IO or not.
73  **/
74  //virtual bool isNetwork () const = 0;
75  virtual bool isNetwork () const
76  {
77  qCCritical(GAMES_PRIVATE_KGAME) << "Calling PURE virtual isNetwork...BAD";
78  return false;
79  }
80 
81  /**
82  This method returns the status of the object, whether it is already
83  (or still) connected to another KMessageIO object or not.
84 
85  This is a pure virtual method, so it has to be implemented in a subclass
86  of KMessageIO.
87  */
88  //virtual bool isConnected () const = 0;
89  virtual bool isConnected () const
90  {
91  qCCritical(GAMES_PRIVATE_KGAME) << "Calling PURE virtual isConnected...BAD";
92  return false;
93  }
94 
95  /**
96  Sets the ID number of this object. This number can for example be used to
97  distinguish several objects in a server.
98 
99  NOTE: Sometimes it is useful to let two connected KMessageIO objects
100  have the same ID number. You have to do so yourself, KMessageIO doesn't
101  change this value on its own!
102  */
103  void setId (quint32 id);
104 
105  /**
106  Queries the ID of this object.
107  */
108  quint32 id ();
109 
110  /**
111  @return 0 in the default implementation. Reimplemented in @ref KMessageSocket.
112  */
113  virtual quint16 peerPort () const { return 0; }
114 
115  /**
116  @return "localhost" in the default implementation. Reimplemented in @ref KMessageSocket
117  */
118  virtual QString peerName () const { return QStringLiteral("localhost"); }
119 
120 
121 Q_SIGNALS:
122  /**
123  This signal is emitted when /e send() on the connected KMessageIO
124  object is called. The parameter contains the same data array in /e msg
125  as was used in /e send().
126  */
127  void received (const QByteArray &msg);
128 
129  /**
130  This signal is emitted when the connection is closed. This can be caused
131  by a hardware error (e.g. broken internet connection) or because the other
132  object was killed.
133 
134  Note: Sometimes a broken connection can be undetected for a long time,
135  or may never be detected at all. So don't rely on this signal!
136  */
137  void connectionBroken ();
138 
139 public Q_SLOTS:
140 
141  /**
142  This slot sends the data block in /e msg to the connected object, that will
143  emit /e received().
144 
145  For a concrete class, you have to subclass /e KMessageIO and overwrite this
146  method. In the subclass, implement this method as an ordinary method, not
147  as a slot! (Otherwise another slot would be defined. It would work, but uses
148  more memory and time.) See /e KMessageSocket for an example implementation.
149  */
150  virtual void send (const QByteArray &msg) = 0;
151 
152 protected:
153  quint32 m_id;
154 };
155 
156 
157 /**
158  \class KMessageSocket kmessageio.h <KGame/KMessageIO>
159 
160  This class implements the message communication using a TCP/IP socket. The
161  object can connect to a server socket, or can use an already connected socket.
162 */
163 
165 {
166  Q_OBJECT
167 
168 public:
169  /**
170  Connects to a server socket on /e host with /e port. host can be an
171  numerical (e.g. "192.168.0.212") or symbolic (e.g. "wave.peter.org")
172  IP address. You can immediately use the /e sendSystem() and
173  /e sendBroadcast() methods. The messages are stored and sent to the
174  receiver after the connection is established.
175 
176  If the connection could not be established (e.g. unknown host or no server
177  socket at this port), the signal /e connectionBroken is emitted.
178  */
179  KMessageSocket (const QString& host, quint16 port, QObject *parent = nullptr );
180 
181  /**
182  Connects to a server socket on /e host with /e port. You can immediately
183  use the /e sendSystem() and /e sendBroadcast() methods. The messages are
184  stored and sent to the receiver after the connection is established.
185 
186  If the connection could not be established (e.g. unknown host or no server
187  socket at this port), the signal /e connectionBroken is emitted.
188  */
189  KMessageSocket (const QHostAddress &host, quint16 port, QObject *parent = nullptr);
190 
191  /**
192  Uses /e socket to do the communication.
193 
194  The socket should already be connected, or at least be in /e connecting
195  state.
196 
197  Note: The /e socket object is then owned by the /e KMessageSocket object.
198  So don't use it otherwise any more and don't delete it. It is deleted
199  together with this KMessageSocket object. (Use 0 as parent for the QSocket
200  object t ensure it is not deleted.)
201  */
202  explicit KMessageSocket (QTcpSocket *socket, QObject *parent = nullptr);
203 
204  /**
205  Uses the socket specified by the socket descriptor socketFD to do the
206  communication. The socket must already be connected.
207 
208  This constructor can be used with a QServerSocket within the (pure
209  virtual) method /e newConnection.
210 
211  Note: The socket is then owned by the /e KMessageSocket object. So don't
212  manipulate the socket afterwards, especially don't close it. The socket is
213  automatically closed when KMessageSocket is deleted.
214  */
215  explicit KMessageSocket (int socketFD, QObject *parent = nullptr);
216 
217  /**
218  Destructor, closes the socket.
219  */
220  ~KMessageSocket () override;
221 
222  /**
223  * The runtime identification
224  */
225  int rtti() const override {return 1;}
226 
227  /**
228  @return The port that this object is connected to. See QSocket::peerPort
229  */
230  quint16 peerPort () const override;
231 
232  /**
233  @return The hostname this object is connected to. See QSocket::peerName.
234  */
235  QString peerName () const override;
236 
237  /**
238  @return TRUE as this is a network IO.
239  */
240  bool isNetwork() const override { return true; }
241 
242  /**
243  Returns true if the socket is in state /e connected.
244  */
245  bool isConnected () const override;
246 
247  /**
248  Overwritten slot method from KMessageIO.
249 
250  Note: It is not declared as a slot method, since the slot is already
251  defined in KMessageIO as a virtual method.
252  */
253  void send (const QByteArray &msg) override;
254 
255 protected Q_SLOTS:
256  virtual void processNewData ();
257 
258 protected:
259  void initSocket ();
260  QTcpSocket *mSocket;
261  bool mAwaitingHeader;
262  quint32 mNextBlockLength;
263 
264  bool isRecursive; // workaround for "bug" in QSocket, Qt 2.2.3 or older
265 };
266 
267 
268 /**
269  \class KMessageDirect kmessageio.h <KGame/KMessageIO>
270 
271  This class implements the message communication using function calls
272  directly. It can only be used when both sides of the message pipe are
273  within the same process. The communication is very fast.
274 
275  To establish a communication, you have to create two instances of
276  KMessageDirect, the first one with no parameters in the constructor,
277  the second one with the first as parameter:
278 
279  /code
280  KMessageDirect *peer1, *peer2;
281  peer1 = new KMessageDirect (); // unconnected
282  peer2 = new KMessageDirect (peer1); // connect with peer1
283  /endcode
284 
285  The connection is only closed when one of the instances is deleted.
286 */
287 
289 {
290  Q_OBJECT
291 
292 public:
293  /**
294  Creates an object and connects it to the object given in the first
295  parameter. Use 0 as first parameter to create an unconnected object,
296  that is later connected.
297 
298  If that object is already connected, the object remains unconnected.
299  */
300  explicit KMessageDirect (KMessageDirect *partner = nullptr, QObject *parent = nullptr);
301 
302  /**
303  Destructor, closes the connection.
304  */
305  ~KMessageDirect () override;
306 
307  /**
308  * The runtime identification
309  */
310  int rtti() const override {return 2;}
311 
312 
313  /**
314  @return FALSE as this is no network IO.
315  */
316  bool isNetwork() const override { return false; }
317 
318  /**
319  Returns true, if the object is connected to another instance.
320 
321  If you use the first constructor, the object is unconnected unless another
322  object is created with this one as parameter.
323 
324  The connection can only be closed by deleting one of the objects.
325  */
326  bool isConnected () const override;
327 
328  /**
329  Overwritten slot method from KMessageIO.
330 
331  Note: It is not declared as a slot method, since the slot is already
332  defined in KMessageIO as a virtual method.
333  */
334  void send (const QByteArray &msg) override;
335 
336 protected:
337  KMessageDirect *mPartner;
338 };
339 
340 /**
341  * \class KMessageProcess kmessageio.h <KGame/KMessageIO>
342  */
343 class KMessageProcess : public KMessageIO
344 {
345  Q_OBJECT
346 
347  public:
348  KMessageProcess(QObject *parent, const QString& file);
349  ~KMessageProcess() override;
350  bool isConnected() const override;
351  void send (const QByteArray &msg) override;
352 
353  /**
354  @return FALSE as this is no network IO.
355  */
356  bool isNetwork() const override { return false; }
357 
358  /**
359  * The runtime identification
360  */
361  int rtti() const override {return 3;}
362 
363 
364 
365  public Q_SLOTS:
366  void slotReceivedStdout();
367  void slotReceivedStderr();
368  void slotProcessExited(int, QProcess::ExitStatus);
369 
370  Q_SIGNALS:
371  void signalReceivedStderr(const QString &msg);
372 
373  private:
374  QString mProcessName;
375  KProcess *mProcess;
376  QByteArray* mSendBuffer;
377  QByteArray mReceiveBuffer;
378  int mReceiveCount;
379 };
380 
381 #endif
382 
This class implements the message communication using a TCP/IP socket.
Definition: kmessageio.h:164
QString peerName() const override
Definition: kmessageio.cpp:161
virtual bool isConnected() const
This method returns the status of the object, whether it is already (or still) connected to another K...
Definition: kmessageio.h:89
virtual int rtti() const
The runtime identification.
Definition: kmessageio.h:69
Q_SIGNALSQ_SIGNALS
This class implements the message communication using function calls directly.
Definition: kmessageio.h:288
int rtti() const override
The runtime identification.
Definition: kmessageio.h:310
void send(const QByteArray &msg) override
Overwritten slot method from KMessageIO.
Definition: kmessageio.cpp:83
Q_OBJECTQ_OBJECT
quint16 peerPort() const override
Definition: kmessageio.cpp:156
This abstract base class represents one end of a message connections between two clients.
Definition: kmessageio.h:51
bool isConnected() const override
Returns true if the socket is in state /e connected.
Definition: kmessageio.cpp:78
bool isNetwork() const override
Definition: kmessageio.h:240
bool isNetwork() const override
Definition: kmessageio.h:316
virtual quint16 peerPort() const
Definition: kmessageio.h:113
virtual bool isNetwork() const
Definition: kmessageio.h:75
virtual QString peerName() const
Definition: kmessageio.h:118
Q_SLOTSQ_SLOTS
QObject * parent() const const
KMessageSocket(const QString &host, quint16 port, QObject *parent=nullptr)
Connects to a server socket on /e host with /e port.
Definition: kmessageio.cpp:42
~KMessageSocket() override
Destructor, closes the socket.
Definition: kmessageio.cpp:73
int rtti() const override
The runtime identification.
Definition: kmessageio.h:225
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Tue Dec 7 2021 22:34:15 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.