/* -*- C++ -*- * Copyright (C) 2003 Thiago Macieira * * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef KSTREAMSOCKET_H #define KSTREAMSOCKET_H #include #include "kclientsocketbase.h" /** A namespace to store all networking-related (socket) classes. */ namespace KNetwork { class KResolverEntry; class KResolverResults; class TDEServerSocket; class TDEBufferedSocket; class KStreamSocketPrivate; /** @class KStreamSocket kstreamsocket.h kstreamsocket.h * @brief Simple stream socket * * This class provides functionality to creating unbuffered, stream * sockets. In the case of Internet (IP) sockets, this class creates and * uses TCP/IP sockets. * * Objects of this class start, by default, on non-blocking mode. Call * setBlocking if you wish to change that. * * KStreamSocket objects are thread-safe and can be used in auxiliary * threads (i.e., not the thread in which the Qt event loop runs in). * Note that TDEBufferedSocket cannot be used reliably in an auxiliary thread. * * Sample usage: * \code * TQByteArray httpGet(const TQString& hostname) * { * KStreamSocket socket(hostname, "http"); * if (!socket.connect()) * return TQByteArray(); * TQByteArray data = socket.readAll(); * return data; * } * \endcode * * Here's another sample, showing asynchronous operation: * \code * DataRetriever::DataRetriever(const TQString& hostname, const TQString& port) * : socket(hostname, port) * { * // connect signals to our slots * TQObject::connect(&socket, TQT_SIGNAL(connected(const KResolverEntry&)), * this, TQT_SLOT(slotSocketConnected())); * TQObject::connect(&socket, TQT_SIGNAL(gotError(int)), * this, TQT_SLOT(slotSocketError(int))); * TQObject::connect(&socket, TQT_SIGNAL(readyRead()), * this, TQT_SLOT(slotSocketReadyToRead())); * TQObject::connect(&socket, TQT_SIGNAL(readyWrite()), * this, TQT_SLOT(slotSocketReadyToWrite())); * * // set non-blocking mode in order to work asynchronously * socket.setBlocking(false); * * // turn on signal emission * socket.enableRead(true); * socket.enableWrite(true); * * // start connecting * socket.connect(); * } * \endcode * * @see KNetwork::TDEBufferedSocket, KNetwork::TDEServerSocket * @author Thiago Macieira */ class TDECORE_EXPORT KStreamSocket: public KClientSocketBase { Q_OBJECT public: /** * Default constructor. * * @param node destination host * @param service destination service to connect to * @param parent the parent TQObject object * @param name name for this object */ KStreamSocket(const TQString& node = TQString::null, const TQString& service = TQString::null, TQObject* parent = 0L, const char *name = 0L); /** * Destructor. This closes the socket. */ virtual ~KStreamSocket(); /** * Retrieves the timeout value (in milliseconds). */ int timeout() const; /** * Retrieves the remaining timeout time (in milliseconds). This value * equals @ref timeout() if there's no connection in progress. */ int remainingTimeout() const; /** * Sets the timeout value. Setting this value while a connection attempt * is in progress will reset the timer. * * Please note that the timeout value is valid for the connection attempt * only. No other operations are timed against this value -- including the * name lookup associated. * * @param msecs the timeout value in milliseconds */ void setTimeout(int msecs); /** * Binds this socket to the given nodename and service, * or use the default ones if none are given. In order to bind to a service * and allow the operating system to choose the interface, set @p node to * TQString::null. * * Reimplemented from KClientSocketBase. * * Upon successful binding, the @ref bound signal will be * emitted. If an error is found, the @ref gotError * signal will be emitted. * * @note Due to the internals of the name lookup and binding * mechanism, some (if not most) implementations of this function * do not actually bind the socket until the connection * is requested (see @ref connect). They only set the values * for future reference. * * This function returns true on success. * * @param node the nodename * @param service the service */ virtual bool bind(const TQString& node = TQString::null, const TQString& service = TQString::null); /** * Reimplemented from KClientSocketBase. Connect this socket to this * specific address. * * Unlike @ref bind(const TQString&, const TQString&) above, this function * really does bind the socket. No lookup is performed. The @ref bound * signal will be emitted. */ virtual bool bind(const KResolverEntry& entry) { return KClientSocketBase::bind(entry); } /** * Reimplemented from KClientSocketBase. * * Attempts to connect to the these hostname and service, * or use the default ones if none are given. If a connection attempt * is already in progress, check on its state and set the error status * (NoError, meaning the connection is completed, or InProgress). * * If the blocking mode for this object is on, this function will only * return when all the resolved peer addresses have been tried or when * a connection is established. * * Upon successfully connecting, the @ref connected signal * will be emitted. If an error is found, the @ref gotError * signal will be emitted. * * This function also implements timeout handling. * * @param node the remote node to connect to * @param service the service on the remote node to connect to */ virtual bool connect(const TQString& node = TQString::null, const TQString& service = TQString::null); /** * Unshadowing from KClientSocketBase. */ virtual bool connect(const KResolverEntry& entry); signals: /** * This signal is emitted when a connection timeout occurs. */ void timedOut(); private slots: void hostFoundSlot(); void connectionEvent(); void timeoutSlot(); private: /** * @internal * If the user requested local bind before connection, bind the socket to one * suitable address and return true. Also sets d->local to the address used. * * Return false in case of error. */ bool bindLocallyFor(const KResolverEntry& peer); /** * @internal * Finishes the connection process by setting internal values and * emitting the proper signals. * * Note: assumes d->local iterator points to the address that we bound * to. */ void connectionSucceeded(const KResolverEntry& peer); KStreamSocket(const KStreamSocket&); KStreamSocket& operator=(const KStreamSocket&); KStreamSocketPrivate *d; friend class TDEServerSocket; friend class TDEBufferedSocket; }; } // namespace KNetwork #endif