Warning, file /games/libkdegames/src/private/kgame/kmessageio.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 This file is part of the KDE games library 0003 SPDX-FileCopyrightText: 2001 Burkhard Lehner <Burkhard.Lehner@gmx.de> 0004 0005 SPDX-License-Identifier: LGPL-2.0-only 0006 */ 0007 0008 /* 0009 KMessageIO class and subclasses KMessageSocket and KMessageDirect 0010 */ 0011 0012 #ifndef _KMESSAGEIO_H_ 0013 #define _KMESSAGEIO_H_ 0014 0015 // own 0016 #include "kdegamesprivate_export.h" 0017 // Qt 0018 #include <QHostAddress> 0019 #include <QObject> 0020 #include <QProcess> 0021 #include <QString> 0022 0023 class QTcpSocket; 0024 class KProcess; 0025 0026 /** 0027 \class KMessageIO kmessageio.h <KGame/KMessageIO> 0028 0029 This abstract base class represents one end of a message connections 0030 between two clients. Each client has one object of a subclass of 0031 KMessageIO. Calling /e send() on one object will emit the signal 0032 /e received() on the other object, and vice versa. 0033 0034 For each type of connection (TCP/IP socket, COM port, direct connection 0035 within the same class) a subclass of KMessageIO must be defined that 0036 implements the pure virtual methods /e send() and /e isConnected(), 0037 and sends the signals. (See /e KMessageSocket for an example implementation.) 0038 0039 Two subclasses are already included: /e KMessageSocket (connection using 0040 TCP/IP sockets) and /e KMessageDirect (connection using method calls, both 0041 sides must be within the same process). 0042 */ 0043 class KDEGAMESPRIVATE_EXPORT KMessageIO : public QObject 0044 { 0045 Q_OBJECT 0046 0047 public: 0048 /** 0049 * The usual QObject constructor, does nothing else. 0050 */ 0051 explicit KMessageIO(QObject *parent = nullptr); 0052 0053 /** 0054 * The usual destructor, does nothing special. 0055 */ 0056 ~KMessageIO() override; 0057 0058 /** 0059 * The runtime identification 0060 */ 0061 virtual int rtti() const 0062 { 0063 return 0; 0064 } 0065 0066 /** 0067 * @return Whether this KMessageIO is a network IO or not. 0068 */ 0069 // virtual bool isNetwork () const = 0; 0070 virtual bool isNetwork() const; 0071 0072 /** 0073 This method returns the status of the object, whether it is already 0074 (or still) connected to another KMessageIO object or not. 0075 0076 This is a pure virtual method, so it has to be implemented in a subclass 0077 of KMessageIO. 0078 */ 0079 // virtual bool isConnected () const = 0; 0080 virtual bool isConnected() const; 0081 0082 /** 0083 Sets the ID number of this object. This number can for example be used to 0084 distinguish several objects in a server. 0085 0086 NOTE: Sometimes it is useful to let two connected KMessageIO objects 0087 have the same ID number. You have to do so yourself, KMessageIO doesn't 0088 change this value on its own! 0089 */ 0090 void setId(quint32 id); 0091 0092 /** 0093 Queries the ID of this object. 0094 */ 0095 quint32 id(); 0096 0097 /** 0098 @return 0 in the default implementation. Reimplemented in @ref KMessageSocket. 0099 */ 0100 virtual quint16 peerPort() const; 0101 0102 /** 0103 @return "localhost" in the default implementation. Reimplemented in @ref KMessageSocket 0104 */ 0105 virtual QString peerName() const; 0106 0107 Q_SIGNALS: 0108 /** 0109 This signal is emitted when /e send() on the connected KMessageIO 0110 object is called. The parameter contains the same data array in /e msg 0111 as was used in /e send(). 0112 */ 0113 void received(const QByteArray &msg); 0114 0115 /** 0116 This signal is emitted when the connection is closed. This can be caused 0117 by a hardware error (e.g. broken internet connection) or because the other 0118 object was killed. 0119 0120 Note: Sometimes a broken connection can be undetected for a long time, 0121 or may never be detected at all. So don't rely on this signal! 0122 */ 0123 void connectionBroken(); 0124 0125 public Q_SLOTS: 0126 0127 /** 0128 This slot sends the data block in /e msg to the connected object, that will 0129 emit /e received(). 0130 0131 For a concrete class, you have to subclass /e KMessageIO and overwrite this 0132 method. In the subclass, implement this method as an ordinary method, not 0133 as a slot! (Otherwise another slot would be defined. It would work, but uses 0134 more memory and time.) See /e KMessageSocket for an example implementation. 0135 */ 0136 virtual void send(const QByteArray &msg) = 0; 0137 0138 protected: 0139 quint32 m_id; 0140 }; 0141 0142 /** 0143 \class KMessageSocket kmessageio.h <KGame/KMessageIO> 0144 0145 This class implements the message communication using a TCP/IP socket. The 0146 object can connect to a server socket, or can use an already connected socket. 0147 */ 0148 0149 class KMessageSocket : public KMessageIO 0150 { 0151 Q_OBJECT 0152 0153 public: 0154 /** 0155 Connects to a server socket on /e host with /e port. host can be an 0156 numerical (e.g. "192.168.0.212") or symbolic (e.g. "wave.peter.org") 0157 IP address. You can immediately use the /e sendSystem() and 0158 /e sendBroadcast() methods. The messages are stored and sent to the 0159 receiver after the connection is established. 0160 0161 If the connection could not be established (e.g. unknown host or no server 0162 socket at this port), the signal /e connectionBroken is emitted. 0163 */ 0164 KMessageSocket(const QString &host, quint16 port, QObject *parent = nullptr); 0165 0166 /** 0167 Connects to a server socket on /e host with /e port. You can immediately 0168 use the /e sendSystem() and /e sendBroadcast() methods. The messages are 0169 stored and sent to the receiver after the connection is established. 0170 0171 If the connection could not be established (e.g. unknown host or no server 0172 socket at this port), the signal /e connectionBroken is emitted. 0173 */ 0174 KMessageSocket(const QHostAddress &host, quint16 port, QObject *parent = nullptr); 0175 0176 /** 0177 Uses /e socket to do the communication. 0178 0179 The socket should already be connected, or at least be in /e connecting 0180 state. 0181 0182 Note: The /e socket object is then owned by the /e KMessageSocket object. 0183 So don't use it otherwise any more and don't delete it. It is deleted 0184 together with this KMessageSocket object. (Use 0 as parent for the QSocket 0185 object t ensure it is not deleted.) 0186 */ 0187 explicit KMessageSocket(QTcpSocket *socket, QObject *parent = nullptr); 0188 0189 /** 0190 Uses the socket specified by the socket descriptor socketFD to do the 0191 communication. The socket must already be connected. 0192 0193 This constructor can be used with a QServerSocket within the (pure 0194 virtual) method /e newConnection. 0195 0196 Note: The socket is then owned by the /e KMessageSocket object. So don't 0197 manipulate the socket afterwards, especially don't close it. The socket is 0198 automatically closed when KMessageSocket is deleted. 0199 */ 0200 explicit KMessageSocket(int socketFD, QObject *parent = nullptr); 0201 0202 /** 0203 Destructor, closes the socket. 0204 */ 0205 ~KMessageSocket() override; 0206 0207 /** 0208 * The runtime identification 0209 */ 0210 int rtti() const override 0211 { 0212 return 1; 0213 } 0214 0215 /** 0216 @return The port that this object is connected to. See QSocket::peerPort 0217 */ 0218 quint16 peerPort() const override; 0219 0220 /** 0221 @return The hostname this object is connected to. See QSocket::peerName. 0222 */ 0223 QString peerName() const override; 0224 0225 /** 0226 @return TRUE as this is a network IO. 0227 */ 0228 bool isNetwork() const override 0229 { 0230 return true; 0231 } 0232 0233 /** 0234 Returns true if the socket is in state /e connected. 0235 */ 0236 bool isConnected() const override; 0237 0238 /** 0239 Overwritten slot method from KMessageIO. 0240 0241 Note: It is not declared as a slot method, since the slot is already 0242 defined in KMessageIO as a virtual method. 0243 */ 0244 void send(const QByteArray &msg) override; 0245 0246 protected Q_SLOTS: 0247 virtual void processNewData(); 0248 0249 protected: 0250 void initSocket(); 0251 QTcpSocket *mSocket; 0252 bool mAwaitingHeader; 0253 quint32 mNextBlockLength; 0254 0255 bool isRecursive; // workaround for "bug" in QSocket, Qt 2.2.3 or older 0256 }; 0257 0258 /** 0259 \class KMessageDirect kmessageio.h <KGame/KMessageIO> 0260 0261 This class implements the message communication using function calls 0262 directly. It can only be used when both sides of the message pipe are 0263 within the same process. The communication is very fast. 0264 0265 To establish a communication, you have to create two instances of 0266 KMessageDirect, the first one with no parameters in the constructor, 0267 the second one with the first as parameter: 0268 0269 /code 0270 KMessageDirect *peer1, *peer2; 0271 peer1 = new KMessageDirect (); // unconnected 0272 peer2 = new KMessageDirect (peer1); // connect with peer1 0273 /endcode 0274 0275 The connection is only closed when one of the instances is deleted. 0276 */ 0277 0278 class KMessageDirect : public KMessageIO 0279 { 0280 Q_OBJECT 0281 0282 public: 0283 /** 0284 Creates an object and connects it to the object given in the first 0285 parameter. Use 0 as first parameter to create an unconnected object, 0286 that is later connected. 0287 0288 If that object is already connected, the object remains unconnected. 0289 */ 0290 explicit KMessageDirect(KMessageDirect *partner = nullptr, QObject *parent = nullptr); 0291 0292 /** 0293 Destructor, closes the connection. 0294 */ 0295 ~KMessageDirect() override; 0296 0297 /** 0298 * The runtime identification 0299 */ 0300 int rtti() const override 0301 { 0302 return 2; 0303 } 0304 0305 /** 0306 @return FALSE as this is no network IO. 0307 */ 0308 bool isNetwork() const override 0309 { 0310 return false; 0311 } 0312 0313 /** 0314 Returns true, if the object is connected to another instance. 0315 0316 If you use the first constructor, the object is unconnected unless another 0317 object is created with this one as parameter. 0318 0319 The connection can only be closed by deleting one of the objects. 0320 */ 0321 bool isConnected() const override; 0322 0323 /** 0324 Overwritten slot method from KMessageIO. 0325 0326 Note: It is not declared as a slot method, since the slot is already 0327 defined in KMessageIO as a virtual method. 0328 */ 0329 void send(const QByteArray &msg) override; 0330 0331 protected: 0332 KMessageDirect *mPartner; 0333 }; 0334 0335 /** 0336 * \class KMessageProcess kmessageio.h <KGame/KMessageIO> 0337 */ 0338 class KMessageProcess : public KMessageIO 0339 { 0340 Q_OBJECT 0341 0342 public: 0343 KMessageProcess(QObject *parent, const QString &file); 0344 ~KMessageProcess() override; 0345 bool isConnected() const override; 0346 void send(const QByteArray &msg) override; 0347 0348 /** 0349 @return FALSE as this is no network IO. 0350 */ 0351 bool isNetwork() const override 0352 { 0353 return false; 0354 } 0355 0356 /** 0357 * The runtime identification 0358 */ 0359 int rtti() const override 0360 { 0361 return 3; 0362 } 0363 0364 public Q_SLOTS: 0365 void slotReceivedStdout(); 0366 void slotReceivedStderr(); 0367 void slotProcessExited(int, QProcess::ExitStatus); 0368 0369 Q_SIGNALS: 0370 void signalReceivedStderr(const QString &msg); 0371 0372 private: 0373 QString mProcessName; 0374 KProcess *mProcess; 0375 QByteArray *mSendBuffer; 0376 QByteArray mReceiveBuffer; 0377 int mReceiveCount; 0378 }; 0379 0380 #endif