File indexing completed on 2024-04-21 14:55:25

0001 /*  -*- C++ -*-
0002  *  Copyright (C) 2003,2005 Thiago Macieira <thiago@kde.org>
0003  *
0004  *
0005  *  Permission is hereby granted, free of charge, to any person obtaining
0006  *  a copy of this software and associated documentation files (the
0007  *  "Software"), to deal in the Software without restriction, including
0008  *  without limitation the rights to use, copy, modify, merge, publish,
0009  *  distribute, sublicense, and/or sell copies of the Software, and to
0010  *  permit persons to whom the Software is furnished to do so, subject to
0011  *  the following conditions:
0012  *
0013  *  The above copyright notice and this permission notice shall be included
0014  *  in all copies or substantial portions of the Software.
0015  *
0016  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
0017  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
0018  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
0019  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
0020  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
0021  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
0022  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
0023  */
0024 
0025 #ifndef KSTREAMSOCKET_H
0026 #define KSTREAMSOCKET_H
0027 
0028 #include <QString>
0029 
0030 #include "k3clientsocketbase.h"
0031 
0032 /** A namespace to store all networking-related (socket) classes. */
0033 namespace KNetwork
0034 {
0035 
0036 class KResolverEntry;
0037 class KServerSocket;
0038 class KBufferedSocket;
0039 
0040 class KStreamSocketPrivate;
0041 /** @class KStreamSocket k3streamsocket.h k3streamsocket.h
0042  *  @brief Simple stream socket
0043  *
0044  * This class provides functionality to creating unbuffered, stream
0045  * sockets. In the case of Internet (IP) sockets, this class creates and
0046  * uses TCP/IP sockets.
0047  *
0048  * Objects of this class start, by default, on non-blocking mode. Call
0049  * setBlocking if you wish to change that.
0050  *
0051  * KStreamSocket objects are thread-safe and can be used in auxiliary
0052  * threads (i.e., not the thread in which the Qt event loop runs in).
0053  * Note that KBufferedSocket cannot be used reliably in an auxiliary thread.
0054  *
0055  * Sample usage:
0056  * \code
0057  *   QByteArray httpGet(const QString& hostname)
0058  *   {
0059  *     KStreamSocket socket(hostname, "http");
0060  *     if (!socket.connect())
0061  *       return QByteArray();
0062  *     QByteArray data = socket.readAll();
0063  *     return data;
0064  *   }
0065  * \endcode
0066  *
0067  * Here's another sample, showing asynchronous operation:
0068  * \code
0069  *  DataRetriever::DataRetriever(const QString& hostname, const QString& port)
0070  *    : socket(hostname, port)
0071  *  {
0072  *    // connect signals to our slots
0073  *    QObject::connect(&socket, SIGNAL(connected(const KNetwork::KResolverEntry&)),
0074  *                     this, SLOT(slotSocketConnected()));
0075  *    QObject::connect(&socket, SIGNAL(gotError(int)),
0076  *                     this, SLOT(slotSocketError(int)));
0077  *    QObject::connect(&socket, SIGNAL(readyRead()),
0078  *                     this, SLOT(slotSocketReadyToRead()));
0079  *    QObject::connect(&socket, SIGNAL(readyWrite()),
0080  *                     this, SLOT(slotSocketReadyToWrite()));
0081  *
0082  *    // set non-blocking mode in order to work asynchronously
0083  *    socket.setBlocking(false);
0084  *
0085  *    // turn on signal emission
0086  *    socket.enableRead(true);
0087  *    socket.enableWrite(true);
0088  *
0089  *    // start connecting
0090  *    socket.connect();
0091  *  }
0092  * \endcode
0093  *
0094  * @see KNetwork::KBufferedSocket, KNetwork::KServerSocket
0095  * @author Thiago Macieira <thiago@kde.org>
0096  * @version 0.9
0097  * @deprecated Use KSocketFactory or KLocalSocket instead
0098  */
0099 class KDELIBS4SUPPORT_DEPRECATED_EXPORT KStreamSocket: public KClientSocketBase
0100 {
0101     Q_OBJECT
0102 
0103 public:
0104     /**
0105      * Default constructor.
0106      *
0107      * @param node    destination host
0108      * @param service destination service to connect to
0109      * @param parent  the parent QObject object
0110      */
0111     KDELIBS4SUPPORT_DEPRECATED explicit KStreamSocket(const QString &node = QString(), const QString &service = QString(),
0112                            QObject *parent = nullptr);
0113 
0114     /**
0115      * Destructor. This closes the socket.
0116      */
0117     ~KStreamSocket() override;
0118 
0119     /**
0120      * Retrieves the timeout value (in milliseconds).
0121      */
0122     int timeout() const;
0123 
0124     /**
0125      * Retrieves the remaining timeout time (in milliseconds). This value
0126      * equals timeout() if there's no connection in progress.
0127      */
0128     int remainingTimeout() const;
0129 
0130     /**
0131      * Sets the timeout value. Setting this value while a connection attempt
0132      * is in progress will reset the timer.
0133      *
0134      * Please note that the timeout value is valid for the connection attempt
0135      * only. No other operations are timed against this value -- including the
0136      * name lookup associated.
0137      *
0138      * @param msecs       the timeout value in milliseconds
0139      */
0140     void setTimeout(int msecs);
0141 
0142     /**
0143      * Binds this socket to the given nodename and service,
0144      * or use the default ones if none are given. In order to bind to a service
0145      * and allow the operating system to choose the interface, set @p node to
0146      * QString().
0147      *
0148      * Reimplemented from KClientSocketBase.
0149      *
0150      * Upon successful binding, the bound() signal will be
0151      * emitted. If an error is found, the gotError()
0152      * signal will be emitted.
0153      *
0154      * @note Due to the internals of the name lookup and binding
0155      *       mechanism, some (if not most) implementations of this function
0156      *       do not actually bind the socket until the connection
0157      *       is requested (see connect()). They only set the values
0158      *       for future reference.
0159      *
0160      * This function returns true on success.
0161      *
0162      * @param node    the nodename
0163      * @param service the service
0164      */
0165     bool bind(const QString &node = QString(),
0166                       const QString &service = QString()) override;
0167 
0168     /**
0169      * Reimplemented from KClientSocketBase. Connect this socket to this
0170      * specific address.
0171      *
0172      * Unlike bind(const QString&, const QString&) above, this function
0173      * really does bind the socket. No lookup is performed. The bound()
0174      * signal will be emitted.
0175      */
0176     bool bind(const KResolverEntry &entry) override;
0177 
0178     /**
0179      * Reimplemented from KClientSocketBase.
0180      *
0181      * Attempts to connect to the these hostname and service,
0182      * or use the default ones if none are given. If a connection attempt
0183      * is already in progress, check on its state and set the error status
0184      * (NoError, meaning the connection is completed, or InProgress).
0185      *
0186      * If the blocking mode for this object is on, this function will only
0187      * return when all the resolved peer addresses have been tried or when
0188      * a connection is established.
0189      *
0190      * Upon successfully connecting, the connected() signal
0191      * will be emitted. If an error is found, the gotError()
0192      * signal will be emitted.
0193      *
0194      * This function also implements timeout handling.
0195      *
0196      * @param node    the remote node to connect to
0197      * @param service the service on the remote node to connect to
0198      * @param mode        mode to operate this socket in
0199      */
0200     bool connect(const QString &node = QString(),
0201                          const QString &service = QString(),
0202                          OpenMode mode = ReadWrite) override;
0203 
0204     /**
0205      * Unshadowing from KClientSocketBase.
0206      */
0207     bool connect(const KResolverEntry &entry,
0208                          OpenMode mode = ReadWrite) override;
0209 
0210 Q_SIGNALS:
0211     /**
0212      * This signal is emitted when a connection timeout occurs.
0213      */
0214     void timedOut();
0215 
0216 private Q_SLOTS:
0217     void hostFoundSlot();
0218     void connectionEvent();
0219     void timeoutSlot();
0220 
0221 private:
0222     /**
0223      * @internal
0224      * If the user requested local bind before connection, bind the socket to one
0225      * suitable address and return true. Also sets d->local to the address used.
0226      *
0227      * Return false in case of error.
0228      */
0229     bool bindLocallyFor(const KResolverEntry &peer);
0230 
0231     /**
0232      * @internal
0233      * Finishes the connection process by setting internal values and
0234      * emitting the proper signals.
0235      *
0236      * Note: assumes d->local iterator points to the address that we bound
0237      * to.
0238      */
0239     void connectionSucceeded(const KResolverEntry &peer);
0240 
0241     KStreamSocket(const KStreamSocket &);
0242     KStreamSocket &operator=(const KStreamSocket &);
0243 
0244     KStreamSocketPrivate *const d;
0245 
0246     friend class KServerSocket;
0247     friend class KBufferedSocket;
0248 };
0249 
0250 }               // namespace KNetwork
0251 
0252 #endif