KDEGames

kmessageio.h
1/*
2 This file is part of the KDE games library
3 SPDX-FileCopyrightText: 2001 Burkhard Lehner <Burkhard.Lehner@gmx.de>
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
23class QTcpSocket;
24class 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*/
43class KDEGAMESPRIVATE_EXPORT KMessageIO : public QObject
44{
45 Q_OBJECT
46
47public:
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
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 */
124
125public 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
138protected:
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{
152
153public:
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
246protected Q_SLOTS:
247 virtual void processNewData();
248
249protected:
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{
281
282public:
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
331protected:
332 KMessageDirect *mPartner;
333};
334
335/**
336 * \class KMessageProcess kmessageio.h <KGame/KMessageIO>
337 */
338class KMessageProcess : public KMessageIO
339{
341
342public:
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
364public Q_SLOTS:
365 void slotReceivedStdout();
366 void slotReceivedStderr();
367 void slotProcessExited(int, QProcess::ExitStatus);
368
370 void signalReceivedStderr(const QString &msg);
371
372private:
373 QString mProcessName;
374 KProcess *mProcess;
375 QByteArray *mSendBuffer;
376 QByteArray mReceiveBuffer;
377 int mReceiveCount;
378};
379
380#endif
This class implements the message communication using function calls directly.
Definition kmessageio.h:279
bool isNetwork() const override
Definition kmessageio.h:308
~KMessageDirect() override
Destructor, closes the connection.
void send(const QByteArray &msg) override
Overwritten slot method from KMessageIO.
KMessageDirect(KMessageDirect *partner=nullptr, QObject *parent=nullptr)
Creates an object and connects it to the object given in the first parameter.
int rtti() const override
The runtime identification.
Definition kmessageio.h:300
bool isConnected() const override
Returns true, if the object is connected to another instance.
This abstract base class represents one end of a message connections between two clients.
Definition kmessageio.h:44
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().
void connectionBroken()
This signal is emitted when the connection is closed.
void received(const QByteArray &msg)
This signal is emitted when /e send() on the connected KMessageIO object is called.
This class implements the message communication using a TCP/IP socket.
Definition kmessageio.h:150
int rtti() const override
The runtime identification.
Definition kmessageio.h:210
~KMessageSocket() override
Destructor, closes the socket.
quint16 peerPort() const override
KMessageSocket(const QString &host, quint16 port, QObject *parent=nullptr)
Connects to a server socket on /e host with /e port.
QString peerName() const override
void send(const QByteArray &msg) override
Overwritten slot method from KMessageIO.
bool isConnected() const override
Returns true if the socket is in state /e connected.
bool isNetwork() const override
Definition kmessageio.h:228
Q_OBJECTQ_OBJECT
Q_SIGNALSQ_SIGNALS
Q_SLOTSQ_SLOTS
QObject * parent() const const
T qobject_cast(QObject *object)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:16:50 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.