1/* -*- C++ -*-
2 * Copyright (C) 2003,2005 Thiago Macieira <thiago@kde.org>
3 *
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25#ifndef KSTREAMSOCKET_H
26#define KSTREAMSOCKET_H
27
28#include <QtCore/QString>
29
30#include "k3clientsocketbase.h"
31
32/** A namespace to store all networking-related (socket) classes. */
33namespace KNetwork {
34
35class KResolverEntry;
36class KServerSocket;
37class KBufferedSocket;
38
39class KStreamSocketPrivate;
40/** @class KStreamSocket k3streamsocket.h k3streamsocket.h
41 * @brief Simple stream socket
42 *
43 * This class provides functionality to creating unbuffered, stream
44 * sockets. In the case of Internet (IP) sockets, this class creates and
45 * uses TCP/IP sockets.
46 *
47 * Objects of this class start, by default, on non-blocking mode. Call
48 * setBlocking if you wish to change that.
49 *
50 * KStreamSocket objects are thread-safe and can be used in auxiliary
51 * threads (i.e., not the thread in which the Qt event loop runs in).
52 * Note that KBufferedSocket cannot be used reliably in an auxiliary thread.
53 *
54 * Sample usage:
55 * \code
56 * QByteArray httpGet(const QString& hostname)
57 * {
58 * KStreamSocket socket(hostname, "http");
59 * if (!socket.connect())
60 * return QByteArray();
61 * QByteArray data = socket.readAll();
62 * return data;
63 * }
64 * \endcode
65 *
66 * Here's another sample, showing asynchronous operation:
67 * \code
68 * DataRetriever::DataRetriever(const QString& hostname, const QString& port)
69 * : socket(hostname, port)
70 * {
71 * // connect signals to our slots
72 * QObject::connect(&socket, SIGNAL(connected(const KNetwork::KResolverEntry&)),
73 * this, SLOT(slotSocketConnected()));
74 * QObject::connect(&socket, SIGNAL(gotError(int)),
75 * this, SLOT(slotSocketError(int)));
76 * QObject::connect(&socket, SIGNAL(readyRead()),
77 * this, SLOT(slotSocketReadyToRead()));
78 * QObject::connect(&socket, SIGNAL(readyWrite()),
79 * this, SLOT(slotSocketReadyToWrite()));
80 *
81 * // set non-blocking mode in order to work asynchronously
82 * socket.setBlocking(false);
83 *
84 * // turn on signal emission
85 * socket.enableRead(true);
86 * socket.enableWrite(true);
87 *
88 * // start connecting
89 * socket.connect();
90 * }
91 * \endcode
92 *
93 * @see KNetwork::KBufferedSocket, KNetwork::KServerSocket
94 * @author Thiago Macieira <thiago@kde.org>
95 * @version 0.9
96 * @deprecated Use KSocketFactory or KLocalSocket instead
97 */
98class KDECORE_EXPORT_DEPRECATED KStreamSocket: public KClientSocketBase
99{
100 Q_OBJECT
101
102public:
103 /**
104 * Default constructor.
105 *
106 * @param node destination host
107 * @param service destination service to connect to
108 * @param parent the parent QObject object
109 */
110 explicit KStreamSocket(const QString& node = QString(), const QString& service = QString(),
111 QObject* parent = 0L);
112
113 /**
114 * Destructor. This closes the socket.
115 */
116 virtual ~KStreamSocket();
117
118 /**
119 * Retrieves the timeout value (in milliseconds).
120 */
121 int timeout() const;
122
123 /**
124 * Retrieves the remaining timeout time (in milliseconds). This value
125 * equals timeout() if there's no connection in progress.
126 */
127 int remainingTimeout() const;
128
129 /**
130 * Sets the timeout value. Setting this value while a connection attempt
131 * is in progress will reset the timer.
132 *
133 * Please note that the timeout value is valid for the connection attempt
134 * only. No other operations are timed against this value -- including the
135 * name lookup associated.
136 *
137 * @param msecs the timeout value in milliseconds
138 */
139 void setTimeout(int msecs);
140
141 /**
142 * Binds this socket to the given nodename and service,
143 * or use the default ones if none are given. In order to bind to a service
144 * and allow the operating system to choose the interface, set @p node to
145 * QString().
146 *
147 * Reimplemented from KClientSocketBase.
148 *
149 * Upon successful binding, the bound() signal will be
150 * emitted. If an error is found, the gotError()
151 * signal will be emitted.
152 *
153 * @note Due to the internals of the name lookup and binding
154 * mechanism, some (if not most) implementations of this function
155 * do not actually bind the socket until the connection
156 * is requested (see connect()). They only set the values
157 * for future reference.
158 *
159 * This function returns true on success.
160 *
161 * @param node the nodename
162 * @param service the service
163 */
164 virtual bool bind(const QString& node = QString(),
165 const QString& service = QString());
166
167 /**
168 * Reimplemented from KClientSocketBase. Connect this socket to this
169 * specific address.
170 *
171 * Unlike bind(const QString&, const QString&) above, this function
172 * really does bind the socket. No lookup is performed. The bound()
173 * signal will be emitted.
174 */
175 virtual bool bind(const KResolverEntry& entry);
176
177 /**
178 * Reimplemented from KClientSocketBase.
179 *
180 * Attempts to connect to the these hostname and service,
181 * or use the default ones if none are given. If a connection attempt
182 * is already in progress, check on its state and set the error status
183 * (NoError, meaning the connection is completed, or InProgress).
184 *
185 * If the blocking mode for this object is on, this function will only
186 * return when all the resolved peer addresses have been tried or when
187 * a connection is established.
188 *
189 * Upon successfully connecting, the connected() signal
190 * will be emitted. If an error is found, the gotError()
191 * signal will be emitted.
192 *
193 * This function also implements timeout handling.
194 *
195 * @param node the remote node to connect to
196 * @param service the service on the remote node to connect to
197 * @param mode mode to operate this socket in
198 */
199 virtual bool connect(const QString& node = QString(),
200 const QString& service = QString(),
201 OpenMode mode = ReadWrite);
202
203 /**
204 * Unshadowing from KClientSocketBase.
205 */
206 virtual bool connect(const KResolverEntry& entry,
207 OpenMode mode = ReadWrite);
208
209Q_SIGNALS:
210 /**
211 * This signal is emitted when a connection timeout occurs.
212 */
213 void timedOut();
214
215private Q_SLOTS:
216 void hostFoundSlot();
217 void connectionEvent();
218 void timeoutSlot();
219
220private:
221 /**
222 * @internal
223 * If the user requested local bind before connection, bind the socket to one
224 * suitable address and return true. Also sets d->local to the address used.
225 *
226 * Return false in case of error.
227 */
228 bool bindLocallyFor(const KResolverEntry& peer);
229
230 /**
231 * @internal
232 * Finishes the connection process by setting internal values and
233 * emitting the proper signals.
234 *
235 * Note: assumes d->local iterator points to the address that we bound
236 * to.
237 */
238 void connectionSucceeded(const KResolverEntry& peer);
239
240 KStreamSocket(const KStreamSocket&);
241 KStreamSocket& operator=(const KStreamSocket&);
242
243 KStreamSocketPrivate* const d;
244
245 friend class KServerSocket;
246 friend class KBufferedSocket;
247};
248
249} // namespace KNetwork
250
251#endif
252