• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • tdecore
 

tdecore

  • tdecore
  • network
kserversocket.cpp
1/*
2 * Copyright (C) 2003 Thiago Macieira <thiago.macieira@kdemail.net>
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#include <config.h>
26
27#include <tqsocketnotifier.h>
28#include <tqmutex.h>
29
30#include "tdesocketaddress.h"
31#include "kresolver.h"
32#include "tdesocketbase.h"
33#include "tdesocketdevice.h"
34#include "kstreamsocket.h"
35#include "kbufferedsocket.h"
36#include "kserversocket.h"
37
38using namespace KNetwork;
39
40class KNetwork::TDEServerSocketPrivate
41{
42public:
43 KResolver resolver;
44 KResolverResults resolverResults;
45
46 enum { None, LookupDone, Bound, Listening } state;
47 int backlog;
48 int timeout;
49
50 bool bindWhenFound : 1, listenWhenBound : 1, useTDEBufferedSocket : 1;
51
52 TDEServerSocketPrivate()
53 : state(None), timeout(0), bindWhenFound(false), listenWhenBound(false),
54 useTDEBufferedSocket(true)
55 {
56 resolver.setFlags(KResolver::Passive);
57 resolver.setFamily(KResolver::KnownFamily);
58 }
59};
60
61TDEServerSocket::TDEServerSocket(TQObject* parent, const char *name)
62 : TQObject(parent, name), d(new TDEServerSocketPrivate)
63{
64 TQObject::connect(&d->resolver, TQ_SIGNAL(finished(KResolverResults)),
65 this, TQ_SLOT(lookupFinishedSlot()));
66}
67
68TDEServerSocket::TDEServerSocket(const TQString& service, TQObject* parent, const char *name)
69 : TQObject(parent, name), d(new TDEServerSocketPrivate)
70{
71 TQObject::connect(&d->resolver, TQ_SIGNAL(finished(KResolverResults)),
72 this, TQ_SLOT(lookupFinishedSlot()));
73 d->resolver.setServiceName(service);
74}
75
76TDEServerSocket::TDEServerSocket(const TQString& node, const TQString& service,
77 TQObject* parent, const char* name)
78 : TQObject(parent, name), d(new TDEServerSocketPrivate)
79{
80 TQObject::connect(&d->resolver, TQ_SIGNAL(finished(KResolverResults)),
81 this, TQ_SLOT(lookupFinishedSlot()));
82 setAddress(node, service);
83}
84
85TDEServerSocket::~TDEServerSocket()
86{
87 close();
88 delete d;
89}
90
91bool TDEServerSocket::setSocketOptions(int opts)
92{
93 TQMutexLocker locker(mutex());
94 TDESocketBase::setSocketOptions(opts); // call parent
95 bool result = socketDevice()->setSocketOptions(opts); // and set the implementation
96 copyError();
97 return result;
98}
99
100KResolver& TDEServerSocket::resolver() const
101{
102 return d->resolver;
103}
104
105const KResolverResults& TDEServerSocket::resolverResults() const
106{
107 return d->resolverResults;
108}
109
110void TDEServerSocket::setResolutionEnabled(bool enable)
111{
112 if (enable)
113 d->resolver.setFlags(d->resolver.flags() & ~KResolver::NoResolve);
114 else
115 d->resolver.setFlags(d->resolver.flags() | KResolver::NoResolve);
116}
117
118void TDEServerSocket::setFamily(int families)
119{
120 d->resolver.setFamily(families);
121}
122
123void TDEServerSocket::setAddress(const TQString& service)
124{
125 d->resolver.setNodeName(TQString::null);
126 d->resolver.setServiceName(service);
127 d->resolverResults.empty();
128 if (d->state <= TDEServerSocketPrivate::LookupDone)
129 d->state = TDEServerSocketPrivate::None;
130}
131
132void TDEServerSocket::setAddress(const TQString& node, const TQString& service)
133{
134 d->resolver.setNodeName(node);
135 d->resolver.setServiceName(service);
136 d->resolverResults.empty();
137 if (d->state <= TDEServerSocketPrivate::LookupDone)
138 d->state = TDEServerSocketPrivate::None;
139}
140
141void TDEServerSocket::setTimeout(int msec)
142{
143 d->timeout = msec;
144}
145
146bool TDEServerSocket::lookup()
147{
148 setError(NoError);
149 if (d->resolver.isRunning() && !blocking())
150 return true; // already doing lookup
151
152 if (d->state >= TDEServerSocketPrivate::LookupDone)
153 return true; // results are already available
154
155 // make sure we have at least one parameter for lookup
156 if (d->resolver.serviceName().isNull() &&
157 !d->resolver.nodeName().isNull())
158 d->resolver.setServiceName(TQString::fromLatin1(""));
159
160 // don't restart the lookups if they had succeeded and
161 // the input values weren't changed
162
163 // reset results
164 d->resolverResults = KResolverResults();
165
166 if (d->resolver.status() <= 0)
167 // if it's already running, there's no harm in calling again
168 d->resolver.start(); // signal may emit
169
170 if (blocking())
171 {
172 // we're in blocking mode operation
173 // wait for the results
174
175 d->resolver.wait(); // signal may be emitted again
176 // lookupFinishedSlot has been called
177 }
178
179 return true;
180}
181
182bool TDEServerSocket::bind(const KResolverEntry& address)
183{
184 if (socketDevice()->bind(address))
185 {
186 setError(NoError);
187
188 d->state = TDEServerSocketPrivate::Bound;
189 emit bound(address);
190 return true;
191 }
192 copyError();
193 return false;
194}
195
196bool TDEServerSocket::bind(const TQString& node, const TQString& service)
197{
198 setAddress(node, service);
199 return bind();
200}
201
202bool TDEServerSocket::bind(const TQString& service)
203{
204 setAddress(service);
205 return bind();
206}
207
208bool TDEServerSocket::bind()
209{
210 if (d->state >= TDEServerSocketPrivate::Bound)
211 return true;
212
213 if (d->state < TDEServerSocketPrivate::LookupDone)
214 {
215 if (!blocking())
216 {
217 d->bindWhenFound = true;
218 bool ok = lookup(); // will call doBind
219 if (d->state >= TDEServerSocketPrivate::Bound)
220 d->bindWhenFound = false;
221 return ok;
222 }
223
224 // not blocking
225 if (!lookup())
226 return false;
227 }
228
229 return doBind();
230}
231
232bool TDEServerSocket::listen(int backlog)
233{
234 // WARNING
235 // this function has to be reentrant
236 // due to the mechanisms used for binding, this function might
237 // end up calling itself
238
239 if (d->state == TDEServerSocketPrivate::Listening)
240 return true; // already listening
241
242 d->backlog = backlog;
243
244 if (d->state < TDEServerSocketPrivate::Bound)
245 {
246 // we must bind
247 // note that we can end up calling ourselves here
248 d->listenWhenBound = true;
249 if (!bind())
250 {
251 d->listenWhenBound = false;
252 return false;
253 }
254
255 if (d->state < TDEServerSocketPrivate::Bound)
256 // asynchronous lookup in progress...
257 // we can't be blocking here anyways
258 return true;
259
260 d->listenWhenBound = false;
261 }
262
263 if (d->state < TDEServerSocketPrivate::Listening)
264 return doListen();
265
266 return true;
267}
268
269void TDEServerSocket::close()
270{
271 socketDevice()->close();
272 if (d->resolver.isRunning())
273 d->resolver.cancel(false);
274 d->state = TDEServerSocketPrivate::None;
275 emit closed();
276}
277
278void TDEServerSocket::setAcceptBuffered(bool enable)
279{
280 d->useTDEBufferedSocket = enable;
281}
282
283KActiveSocketBase* TDEServerSocket::accept()
284{
285 if (d->state < TDEServerSocketPrivate::Listening)
286 {
287 if (!blocking())
288 {
289 listen();
290 setError(WouldBlock);
291 return NULL;
292 }
293 else if (!listen())
294 // error happened during listen
295 return 0L;
296 }
297
298 // check to see if we're doing a timeout
299 if (blocking() && d->timeout > 0)
300 {
301 bool timedout;
302 if (!socketDevice()->poll(d->timeout, &timedout))
303 {
304 copyError();
305 return NULL;
306 }
307
308 if (timedout)
309 return 0L;
310 }
311
312 // we're listening here
313 TDESocketDevice* accepted = socketDevice()->accept();
314 if (!accepted)
315 {
316 // error happened during accept
317 copyError();
318 return NULL;
319 }
320
321 KStreamSocket* streamsocket;
322 if (d->useTDEBufferedSocket)
323 streamsocket = new TDEBufferedSocket();
324 else
325 streamsocket = new KStreamSocket();
326 streamsocket->setSocketDevice(accepted);
327
328 // FIXME!
329 // when KStreamSocket can find out the state of the socket passed through
330 // setSocketDevice, this will probably be unnecessary:
331 streamsocket->setState(KStreamSocket::Connected);
332 streamsocket->setFlags(IO_Sequential | IO_Raw | IO_ReadWrite | IO_Open | IO_Async);
333
334 return streamsocket;
335}
336
337TDESocketAddress TDEServerSocket::localAddress() const
338{
339 return socketDevice()->localAddress();
340}
341
342TDESocketAddress TDEServerSocket::externalAddress() const
343{
344 return socketDevice()->externalAddress();
345}
346
347void TDEServerSocket::lookupFinishedSlot()
348{
349 if (d->resolver.isRunning() || d->state > TDEServerSocketPrivate::LookupDone)
350 return;
351
352 if (d->resolver.status() < 0)
353 {
354 setError(LookupFailure);
355 emit gotError(LookupFailure);
356 d->bindWhenFound = d->listenWhenBound = false;
357 d->state = TDEServerSocketPrivate::None;
358 return;
359 }
360
361 // lookup succeeded
362 d->resolverResults = d->resolver.results();
363 d->state = TDEServerSocketPrivate::LookupDone;
364 emit hostFound();
365
366 if (d->bindWhenFound)
367 doBind();
368}
369
370void TDEServerSocket::copyError()
371{
372 setError(socketDevice()->error());
373}
374
375bool TDEServerSocket::doBind()
376{
377 d->bindWhenFound = false;
378 // loop through the results and bind to the first that works
379
380 KResolverResults::ConstIterator it = d->resolverResults.begin();
381 for ( ; it != d->resolverResults.end(); ++it)
382 if (bind(*it))
383 {
384 if (d->listenWhenBound)
385 return doListen();
386 return true;
387 }
388 else
389 socketDevice()->close(); // didn't work, try again
390
391 // failed to bind
392 emit gotError(error());
393 return false;
394}
395
396bool TDEServerSocket::doListen()
397{
398 if (!socketDevice()->listen(d->backlog))
399 {
400 copyError();
401 emit gotError(error());
402 return false; // failed to listen
403 }
404
405 // set up ready accept signal
406 TQObject::connect(socketDevice()->readNotifier(), TQ_SIGNAL(activated(int)),
407 this, TQ_SIGNAL(readyAccept()));
408 d->state = TDEServerSocketPrivate::Listening;
409 return true;
410}
411
412
413#include "kserversocket.moc"
KNetwork::KActiveSocketBase
Abstract class for active sockets.
Definition: tdesocketbase.h:444
KNetwork::KClientSocketBase::setState
void setState(SocketState state)
Sets the socket state to state.
Definition: kclientsocketbase.cpp:69
KNetwork::KResolverEntry
One resolution entry.
Definition: kresolver.h:67
KNetwork::KResolverResults
Name and service resolution results.
Definition: kresolver.h:198
KNetwork::KResolver
Name and service resolution class.
Definition: kresolver.h:296
KNetwork::KResolver::setFamily
void setFamily(int families)
Sets the allowed socket families.
Definition: kresolver.cpp:401
KNetwork::KResolver::setFlags
int setFlags(int flags)
Sets the flags.
Definition: kresolver.cpp:389
KNetwork::KStreamSocket
Simple stream socket.
Definition: kstreamsocket.h:98
KNetwork::TDEBufferedSocket
Buffered stream sockets.
Definition: kbufferedsocket.h:59
KNetwork::TDEServerSocket::close
virtual void close()
Closes this socket.
Definition: kserversocket.cpp:269
KNetwork::TDEServerSocket::localAddress
virtual TDESocketAddress localAddress() const
Returns this socket's local address.
Definition: kserversocket.cpp:337
KNetwork::TDEServerSocket::readyAccept
void readyAccept()
This signal is emitted whenever the socket is ready for accepting – i.e., there is at least one conne...
KNetwork::TDEServerSocket::resolver
KResolver & resolver() const
Returns the internal KResolver object used for looking up the host name and service.
Definition: kserversocket.cpp:100
KNetwork::TDEServerSocket::bound
void bound(const KResolverEntry &local)
This signal is emitted when the socket successfully binds to an address.
KNetwork::TDEServerSocket::gotError
void gotError(int code)
This signal is emitted when this object finds an error.
KNetwork::TDEServerSocket::closed
void closed()
This signal is emitted when the socket completes the closing/shut down process.
KNetwork::TDEServerSocket::setFamily
void setFamily(int families)
Sets the allowed families for the resolutions.
Definition: kserversocket.cpp:118
KNetwork::TDEServerSocket::setTimeout
void setTimeout(int msecs)
Sets the timeout for accepting.
Definition: kserversocket.cpp:141
KNetwork::TDEServerSocket::setSocketOptions
virtual bool setSocketOptions(int opts)
Sets the socket options.
Definition: kserversocket.cpp:91
KNetwork::TDEServerSocket::setResolutionEnabled
void setResolutionEnabled(bool enable)
Enables or disables name resolution.
Definition: kserversocket.cpp:110
KNetwork::TDEServerSocket::accept
virtual KActiveSocketBase * accept()
Accepts one incoming connection and return the associated, open socket.
Definition: kserversocket.cpp:283
KNetwork::TDEServerSocket::externalAddress
virtual TDESocketAddress externalAddress() const
Returns this socket's externally-visible address if know.
Definition: kserversocket.cpp:342
KNetwork::TDEServerSocket::listen
virtual bool listen(int backlog=5)
Puts this socket into listening mode.
Definition: kserversocket.cpp:232
KNetwork::TDEServerSocket::copyError
void copyError()
Convenience function to set this object's error code to match that of the socket device.
Definition: kserversocket.cpp:370
KNetwork::TDEServerSocket::~TDEServerSocket
~TDEServerSocket()
Destructor.
Definition: kserversocket.cpp:85
KNetwork::TDEServerSocket::lookup
virtual bool lookup()
Starts the lookup for peer and local hostnames as well as their services.
Definition: kserversocket.cpp:146
KNetwork::TDEServerSocket::TDEServerSocket
TDEServerSocket(TQObject *parent=0L, const char *name=0L)
Default constructor.
Definition: kserversocket.cpp:61
KNetwork::TDEServerSocket::setAddress
void setAddress(const TQString &service)
Sets the address on which we will listen.
Definition: kserversocket.cpp:123
KNetwork::TDEServerSocket::bind
virtual bool bind()
Binds the socket to the addresses previously set with setAddress.
Definition: kserversocket.cpp:208
KNetwork::TDEServerSocket::hostFound
void hostFound()
This signal is emitted when the lookup is successfully completed.
KNetwork::TDEServerSocket::setAcceptBuffered
void setAcceptBuffered(bool enable)
Toggles whether the accepted socket will be buffered or not.
Definition: kserversocket.cpp:278
KNetwork::TDEServerSocket::resolverResults
const KResolverResults & resolverResults() const
Returns the internal list of resolved results for the binding address.
Definition: kserversocket.cpp:105
KNetwork::TDESocketAddress
A generic socket address.
Definition: tdesocketaddress.h:424
KNetwork::TDESocketBase::setSocketDevice
virtual void setSocketDevice(TDESocketDevice *device)
Sets the socket implementation to be used on this socket.
Definition: tdesocketbase.cpp:136
KNetwork::TDESocketBase::mutex
TQMutex * mutex() const
Returns the internal mutex for this class.
Definition: tdesocketbase.cpp:278
KNetwork::TDESocketBase::error
SocketError error() const
Retrieves the socket error code.
Definition: tdesocketbase.cpp:160
KNetwork::TDESocketBase::setError
void setError(SocketError error)
Sets the socket's error code.
Definition: tdesocketbase.cpp:155
KNetwork::TDESocketBase::blocking
bool blocking() const
Retrieves this socket's blocking mode.
Definition: tdesocketbase.cpp:81
KNetwork::TDESocketBase::socketDevice
TDESocketDevice * socketDevice() const
Retrieves the socket implementation used on this socket.
Definition: tdesocketbase.cpp:116
KNetwork::TDESocketBase::setSocketOptions
virtual bool setSocketOptions(int opts)
Set the given socket options.
Definition: tdesocketbase.cpp:65
KNetwork::TDESocketDevice
Low-level socket functionality.
Definition: tdesocketdevice.h:51
KNetwork::TDESocketDevice::externalAddress
virtual TDESocketAddress externalAddress() const
Returns this socket's externally visible local address.
Definition: tdesocketdevice.cpp:602
KNetwork::TDESocketDevice::setSocketOptions
virtual bool setSocketOptions(int opts)
This implementation sets the options on the socket.
Definition: tdesocketdevice.cpp:110
KNetwork::TDESocketDevice::close
virtual void close()
Closes the socket.
Definition: tdesocketdevice.cpp:180
KNetwork::TDESocketDevice::accept
virtual TDESocketDevice * accept()
Accepts a new incoming connection.
Definition: tdesocketdevice.cpp:309
KNetwork::TDESocketDevice::localAddress
virtual TDESocketAddress localAddress() const
Returns this socket's local address.
Definition: tdesocketdevice.cpp:530
TDEServerSocket::TDEServerSocket
TDEServerSocket(unsigned short int _port, bool _bind=true)
Constructor.
Definition: ksock.cpp:301
KNetwork
A namespace to store all networking-related (socket) classes.
Definition: kbufferedsocket.h:36

tdecore

Skip menu "tdecore"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

tdecore

Skip menu "tdecore"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdecore by doxygen 1.9.4
This website is maintained by Timothy Pearson.