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

KDE's Doxygen guidelines are available online.