1 | /* |
2 | * This file is part of the KDE libraries |
3 | * Copyright (C) 2007 Thiago Macieira <thiago@kde.org> |
4 | * |
5 | * This library is free software; you can redistribute it and/or |
6 | * modify it under the terms of the GNU Library General Public |
7 | * License as published by the Free Software Foundation; either |
8 | * version 2 of the License, or (at your option) any later version. |
9 | * |
10 | * This library is distributed in the hope that it will be useful, |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | * Library General Public License for more details. |
14 | * |
15 | * You should have received a copy of the GNU Library General Public License |
16 | * along with this library; see the file COPYING.LIB. If not, write to |
17 | * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
18 | * Boston, MA 02110-1301, USA. |
19 | */ |
20 | |
21 | #ifndef KLOCALSOCKET_H |
22 | #define KLOCALSOCKET_H |
23 | |
24 | #include <kdecore_export.h> |
25 | #include <QtCore/QString> |
26 | #include <QtNetwork/QTcpSocket> |
27 | #include <QtNetwork/QTcpServer> |
28 | |
29 | class KLocalSocketPrivate; |
30 | /** |
31 | * @class KLocalSocket |
32 | * @brief KLocalSocket allows one to create and use local (Unix) sockets |
33 | * |
34 | * On some platforms, local sockets are a kind of streaming socket |
35 | * that can be used to transmit and receive data just like Internet |
36 | * (TCP) streaming sockets. The difference is that they remain local |
37 | * to the host running them and cannot be accessed externally. They |
38 | * are also very fast and (in theory) consume less resources than |
39 | * standard TCP sockets. |
40 | * |
41 | * KLocalSocket supports two kinds of local socket types (see |
42 | * KLocalSocket::LocalSocketType): |
43 | * - Unix sockets (UnixSocket): standard Unix sockets whose names are |
44 | * file paths and obey filesystem restrictions |
45 | * - Abstract Unix sockets (AbstractUnixSocket): similar to Unix |
46 | * sockets, but they don't exist as entries in the filesystem and, |
47 | * thus, aren't restricted by its permissions |
48 | * |
49 | * @author Thiago Macieira <thiago@kde.org> |
50 | */ |
51 | class KDECORE_EXPORT KLocalSocket : public QTcpSocket |
52 | { |
53 | Q_OBJECT |
54 | public: |
55 | /** |
56 | * Defines the local socket type. See KLocalSocket for more |
57 | * information |
58 | */ |
59 | enum LocalSocketType { |
60 | UnixSocket, ///< Unix sockets |
61 | AbstractUnixSocket, ///< Abstract Unix sockets |
62 | UnknownLocalSocketType = -1 |
63 | }; |
64 | |
65 | /** |
66 | * Creates a KLocalSocket object with @p parent as the parent |
67 | * object. |
68 | * |
69 | * @param parent the parent object |
70 | */ |
71 | explicit KLocalSocket(QObject *parent = 0); |
72 | /** |
73 | * Destroys the KLocalSocket object and frees up any resources |
74 | * associated. If the socket is open, it will be closed. |
75 | */ |
76 | virtual ~KLocalSocket(); |
77 | |
78 | /** |
79 | * Opens a connection to a listening Unix socket at @p path. Use |
80 | * waitForConnection() to find out if the connection succeeded or |
81 | * not. |
82 | * |
83 | * @param path the Unix socket to connect to |
84 | * @param mode the mode to use when opening (see QIODevice::OpenMode) |
85 | */ |
86 | void connectToPath(const QString &path, OpenMode mode = ReadWrite); |
87 | /** |
88 | * @overload |
89 | * Opens a connection to a listening local socket at address @p |
90 | * path. Use waitForConnection() to find out if the connection |
91 | * succeeded or not. |
92 | * |
93 | * @param path the local socket address to connect to |
94 | * @param type the local socket type to use |
95 | * @param mode the mode to use when opening (see QIODevice::OpenMode) |
96 | */ |
97 | void connectToPath(const QString &path, LocalSocketType type, OpenMode mode = ReadWrite); |
98 | /** |
99 | * Disconnects the socket from its server. |
100 | */ |
101 | void disconnectFromPath(); |
102 | |
103 | /** |
104 | * Returns the socket type for this socket, when |
105 | * connected. Returns UnknownLocalSocketType if not |
106 | * connected. |
107 | */ |
108 | LocalSocketType localSocketType() const; |
109 | |
110 | /** |
111 | * Returns the local address of this socket, when |
112 | * connected. Returns QString() if not connected. |
113 | * |
114 | * Most of the time, the socket has no local address. |
115 | */ |
116 | QString localPath() const; |
117 | /** |
118 | * Returns the peer address of this socket. That is, the address |
119 | * that this socket connected to (see connectToPath). Returns |
120 | * QString() if not connected. |
121 | */ |
122 | QString peerPath() const; |
123 | |
124 | private: |
125 | using QAbstractSocket::connectToHost; |
126 | using QAbstractSocket::disconnectFromHost; |
127 | |
128 | protected Q_SLOTS: |
129 | /// @internal |
130 | void connectToHostImplementation(const QString &hostName, quint16 port, OpenMode mode); |
131 | void disconnectFromHostImplementation(); |
132 | |
133 | private: |
134 | Q_DISABLE_COPY(KLocalSocket) |
135 | friend class KLocalSocketPrivate; |
136 | KLocalSocketPrivate * const d; |
137 | }; |
138 | |
139 | class KLocalSocketServerPrivate; |
140 | /** |
141 | * @class KLocalSocketServer |
142 | * @brief KLocalSocketServer allows one to create a listening local |
143 | * socket and accept incoming connections |
144 | * |
145 | * On some platforms, local sockets are a kind of streaming socket |
146 | * that can be used to transmit and receive data just like Internet |
147 | * (TCP) streaming sockets. The difference is that they remain local |
148 | * to the host running them and cannot be accessed externally. They |
149 | * are also very fast and (in theory) consume less resources than |
150 | * standard TCP sockets. |
151 | * |
152 | * KLocalSocketServer allows you to create the listening (i.e., |
153 | * passive) end of this local socket and accept incoming connections |
154 | * from users of KLocalSocket. It supports the same kind of socket |
155 | * types that KLocalSocket does (see KLocalSocket::LocalSocketType). |
156 | * |
157 | * @author Thiago Macieira <thiago@kde.org> |
158 | */ |
159 | class KDECORE_EXPORT KLocalSocketServer : public QObject |
160 | { |
161 | Q_OBJECT |
162 | public: |
163 | /** |
164 | * Creates a KLocalSocketServer object with @p parent as the |
165 | * parent object. The object is created without binding to any |
166 | * address. |
167 | * |
168 | * @param parent the parent object |
169 | */ |
170 | explicit KLocalSocketServer(QObject *parent = 0); |
171 | /** |
172 | * Destroys the KLocalSocketServer object and frees up any |
173 | * resource associated. If the socket is still listening, it's |
174 | * closed (see close()). |
175 | * |
176 | * The sockets that were accepted using this KLocalSocketServer |
177 | * object are not affected and will remain open. However, note |
178 | * that nextPendingConnection() returns objects that have this |
179 | * KLocalSocketServer as parents, so the QObject destruction will |
180 | * delete any objects that were not reparented. |
181 | */ |
182 | virtual ~KLocalSocketServer(); |
183 | |
184 | /** |
185 | * Binds this socket to the address @p path and starts listening |
186 | * there. |
187 | * |
188 | * If @p type is KLocalSocket::UnixSocket, @p path is |
189 | * treated as a Unix filesystem path and the calling user must |
190 | * have permission to create the named directory entry (that is, |
191 | * the user must have write permission to the parent directory, |
192 | * etc.) |
193 | * |
194 | * If @p type is KLocalSocket::AbstractUnixSocket, @p path is |
195 | * just a name that can be anything. It'll be converted to an |
196 | * 8-bit identifier just as if it were a file path, but |
197 | * filesystem restrictions do not apply. |
198 | * |
199 | * This function returns true if it succeeded in binding the |
200 | * socket to @p path and placing it in listen mode. It returns |
201 | * false otherwise. |
202 | * |
203 | * @param path the path to listen on |
204 | * @param type the local socket type |
205 | * @returns true on success, false otherwise |
206 | */ |
207 | bool listen(const QString &path, KLocalSocket::LocalSocketType type = KLocalSocket::UnixSocket); |
208 | |
209 | /** |
210 | * Closes the socket. No further connections will be accepted, |
211 | * but connections that were already pending can still be |
212 | * retrieved with nextPendingConnection(). |
213 | * |
214 | * Connections that were accepted and are already open will not |
215 | * be affected. |
216 | */ |
217 | void close(); |
218 | |
219 | /** |
220 | * Returns true if the socket is listening, false otherwise. |
221 | */ |
222 | bool isListening() const; |
223 | |
224 | /** |
225 | * Sets the maximum number of connections that KLocalSocketServer |
226 | * will accept on your behalf and keep queued, ready to be |
227 | * retrieved with nextPendingConnection(). If you set @p |
228 | * numConnections to 0, hasPendingConnections() will always |
229 | * return false. You can still use waitForNewConnection(), |
230 | * though. |
231 | * |
232 | * @param numConnections the number of connections to accept |
233 | * and keep queued. |
234 | */ |
235 | void setMaxPendingConnections(int numConnections); |
236 | /** |
237 | * Returns the value set with setMaxPendingConnections(). |
238 | */ |
239 | int maxPendingConnections() const; |
240 | |
241 | /** |
242 | * Returns the socket type that this socket is listening on. If it |
243 | * is not listening, returns QAbstractSocket::UnknownLocalSocketType. |
244 | */ |
245 | KLocalSocket::LocalSocketType localSocketType() const; |
246 | /** |
247 | * Returns the address of this socket if it is listening on, or |
248 | * QString() if it is not listening. |
249 | */ |
250 | QString localPath() const; |
251 | |
252 | /** |
253 | * Suspends the execution of the calling thread for at most @p |
254 | * msec milliseconds and wait for a new socket connection to be |
255 | * accepted (whichever comes first). If no new socket connection |
256 | * is received within @p msec milliseconds, consider this a |
257 | * time-out and set the boolean pointed by @p timedOut to false |
258 | * (if it's not 0). |
259 | * |
260 | * If @p msec is 0, this call will not block, but will simply poll |
261 | * the system to check if a new connection has been received in |
262 | * the background. |
263 | * |
264 | * Use @p msec value of -1 to block indefinitely. |
265 | * |
266 | * @param msec the time in milliseconds to block at most (-1 |
267 | * to block forever) |
268 | * @param timedOut points to a boolean that will be set to true |
269 | * if a timeout did occur |
270 | * @returns true if a new connection has been accepted or false if |
271 | * an error occurred or if the operation timed out. |
272 | */ |
273 | bool waitForNewConnection(int msec = 0, bool *timedOut = 0); |
274 | |
275 | /** |
276 | * Returns true if a new socket can be received with |
277 | * nextPendingConnection(). |
278 | */ |
279 | virtual bool hasPendingConnections() const; |
280 | /** |
281 | * Returns a new socket if one is available or 0 if none is. |
282 | * |
283 | * Note that the objects returned by this function will have the |
284 | * current KLocalSocketServer object as its parent. You may want |
285 | * to reparent the accepted objects if you intend them to outlive |
286 | * the current object. |
287 | */ |
288 | virtual KLocalSocket *nextPendingConnection(); |
289 | |
290 | /** |
291 | * If an error occurred, return the error code. |
292 | */ |
293 | QAbstractSocket::SocketError serverError() const; |
294 | /** |
295 | * If an error occurred, return the error message. |
296 | */ |
297 | QString errorString() const; |
298 | |
299 | protected: |
300 | /// @internal |
301 | virtual void incomingConnection(int handle); |
302 | |
303 | Q_SIGNALS: |
304 | /** |
305 | * The newConnection() signal is emitted whenever a new connection |
306 | * is ready and has been accepted. Whenever it is emitted, calling |
307 | * nextPendingConnection() will return a valid object at least |
308 | * once. |
309 | */ |
310 | void newConnection(); |
311 | |
312 | private: |
313 | Q_PRIVATE_SLOT(d, void _k_newConnectionActivity()) |
314 | Q_DISABLE_COPY(KLocalSocketServer) |
315 | friend class KLocalSocketServerPrivate; |
316 | KLocalSocketServerPrivate * const d; |
317 | }; |
318 | |
319 | #endif |
320 | |