• 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 
38 using namespace KNetwork;
39 
40 class KNetwork::TDEServerSocketPrivate
41 {
42 public:
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 
61 TDEServerSocket::TDEServerSocket(TQObject* parent, const char *name)
62  : TQObject(parent, name), d(new TDEServerSocketPrivate)
63 {
64  TQObject::connect(&d->resolver, TQT_SIGNAL(finished(KResolverResults)),
65  this, TQT_SLOT(lookupFinishedSlot()));
66 }
67 
68 TDEServerSocket::TDEServerSocket(const TQString& service, TQObject* parent, const char *name)
69  : TQObject(parent, name), d(new TDEServerSocketPrivate)
70 {
71  TQObject::connect(&d->resolver, TQT_SIGNAL(finished(KResolverResults)),
72  this, TQT_SLOT(lookupFinishedSlot()));
73  d->resolver.setServiceName(service);
74 }
75 
76 TDEServerSocket::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, TQT_SIGNAL(finished(KResolverResults)),
81  this, TQT_SLOT(lookupFinishedSlot()));
82  setAddress(node, service);
83 }
84 
85 TDEServerSocket::~TDEServerSocket()
86 {
87  close();
88  delete d;
89 }
90 
91 bool 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 
100 KResolver& TDEServerSocket::resolver() const
101 {
102  return d->resolver;
103 }
104 
105 const KResolverResults& TDEServerSocket::resolverResults() const
106 {
107  return d->resolverResults;
108 }
109 
110 void 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 
118 void TDEServerSocket::setFamily(int families)
119 {
120  d->resolver.setFamily(families);
121 }
122 
123 void 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 
132 void 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 
141 void TDEServerSocket::setTimeout(int msec)
142 {
143  d->timeout = msec;
144 }
145 
146 bool 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 
182 bool 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 
196 bool TDEServerSocket::bind(const TQString& node, const TQString& service)
197 {
198  setAddress(node, service);
199  return bind();
200 }
201 
202 bool TDEServerSocket::bind(const TQString& service)
203 {
204  setAddress(service);
205  return bind();
206 }
207 
208 bool 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 
232 bool 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 
269 void 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 
278 void TDEServerSocket::setAcceptBuffered(bool enable)
279 {
280  d->useTDEBufferedSocket = enable;
281 }
282 
283 KActiveSocketBase* 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 
337 TDESocketAddress TDEServerSocket::localAddress() const
338 {
339  return socketDevice()->localAddress();
340 }
341 
342 TDESocketAddress TDEServerSocket::externalAddress() const
343 {
344  return socketDevice()->externalAddress();
345 }
346 
347 void 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 
370 void TDEServerSocket::copyError()
371 {
372  setError(socketDevice()->error());
373 }
374 
375 bool 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 
396 bool 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(), TQT_SIGNAL(activated(int)),
407  this, TQT_SIGNAL(readyAccept()));
408  d->state = TDEServerSocketPrivate::Listening;
409  return true;
410 }
411 
412 
413 #include "kserversocket.moc"
KNetwork::TDEServerSocket::~TDEServerSocket
~TDEServerSocket()
Destructor.
Definition: kserversocket.cpp:85
KNetwork::TDESocketAddress
A generic socket address.
Definition: tdesocketaddress.h:423
KNetwork::TDESocketBase::setSocketDevice
virtual void setSocketDevice(TDESocketDevice *device)
Sets the socket implementation to be used on this socket.
Definition: tdesocketbase.cpp:136
KNetwork::TDEServerSocket::hostFound
void hostFound()
This signal is emitted when the lookup is successfully completed.
KNetwork::KStreamSocket
Simple stream socket.
Definition: kstreamsocket.h:97
KNetwork::TDEServerSocket::setSocketOptions
virtual bool setSocketOptions(int opts)
Sets the socket options.
Definition: kserversocket.cpp:91
KNetwork::TDESocketDevice::externalAddress
virtual TDESocketAddress externalAddress() const
Returns this socket's externally visible local address.
Definition: tdesocketdevice.cpp:607
KNetwork::TDEServerSocket::externalAddress
virtual TDESocketAddress externalAddress() const
Returns this socket's externally-visible address if know.
Definition: kserversocket.cpp:342
KNetwork::TDESocketBase::blocking
bool blocking() const
Retrieves this socket's blocking mode.
Definition: tdesocketbase.cpp:81
KNetwork::KActiveSocketBase
Abstract class for active sockets.
Definition: tdesocketbase.h:443
KNetwork::KResolverEntry
One resolution entry.
Definition: kresolver.h:66
KNetwork::TDESocketDevice::accept
virtual TDESocketDevice * accept()
Accepts a new incoming connection.
Definition: tdesocketdevice.cpp:309
KNetwork::TDEServerSocket::closed
void closed()
This signal is emitted when the socket completes the closing/shut down process.
KNetwork::TDESocketBase::mutex
TQMutex * mutex() const
Returns the internal mutex for this class.
Definition: tdesocketbase.cpp:278
KNetwork::KResolver::setFamily
void setFamily(int families)
Sets the allowed socket families.
Definition: kresolver.cpp:401
KNetwork::KResolver
Name and service resolution class.
Definition: kresolver.h:295
KNetwork::TDEServerSocket::setAcceptBuffered
void setAcceptBuffered(bool enable)
Toggles whether the accepted socket will be buffered or not.
Definition: kserversocket.cpp:278
KNetwork::TDESocketDevice
Low-level socket functionality.
Definition: tdesocketdevice.h:50
KNetwork::TDEServerSocket::listen
virtual bool listen(int backlog=5)
Puts this socket into listening mode.
Definition: kserversocket.cpp:232
KNetwork::TDEServerSocket::setAddress
void setAddress(const TQString &service)
Sets the address on which we will listen.
Definition: kserversocket.cpp:123
KNetwork::TDEServerSocket::TDEServerSocket
TDEServerSocket(TQObject *parent=0L, const char *name=0L)
Default constructor.
Definition: kserversocket.cpp:61
KNetwork::TDESocketBase::error
SocketError error() const
Retrieves the socket error code.
Definition: tdesocketbase.cpp:160
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::KResolverResults
Name and service resolution results.
Definition: kresolver.h:197
KNetwork::TDEServerSocket::bound
void bound(const KResolverEntry &local)
This signal is emitted when the socket successfully binds to an address.
KNetwork
A namespace to store all networking-related (socket) classes.
Definition: kbufferedsocket.h:36
KNetwork::TDEServerSocket::resolverResults
const KResolverResults & resolverResults() const
Returns the internal list of resolved results for the binding address.
Definition: kserversocket.cpp:105
KNetwork::TDEServerSocket::gotError
void gotError(int code)
This signal is emitted when this object finds an error.
KNetwork::TDEServerSocket::localAddress
virtual TDESocketAddress localAddress() const
Returns this socket's local address.
Definition: kserversocket.cpp:337
KNetwork::TDEServerSocket::setTimeout
void setTimeout(int msecs)
Sets the timeout for accepting.
Definition: kserversocket.cpp:141
KNetwork::KClientSocketBase::setState
void setState(SocketState state)
Sets the socket state to state.
Definition: kclientsocketbase.cpp:77
KNetwork::TDESocketBase::socketDevice
TDESocketDevice * socketDevice() const
Retrieves the socket implementation used on this socket.
Definition: tdesocketbase.cpp:116
KNetwork::TDEServerSocket::accept
virtual KActiveSocketBase * accept()
Accepts one incoming connection and return the associated, open socket.
Definition: kserversocket.cpp:283
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::close
virtual void close()
Closes this socket.
Definition: kserversocket.cpp:269
KNetwork::TDEServerSocket::setResolutionEnabled
void setResolutionEnabled(bool enable)
Enables or disables name resolution.
Definition: kserversocket.cpp:110
KNetwork::TDEServerSocket::setFamily
void setFamily(int families)
Sets the allowed families for the resolutions.
Definition: kserversocket.cpp:118
KNetwork::TDESocketDevice::setSocketOptions
virtual bool setSocketOptions(int opts)
This implementation sets the options on the socket.
Definition: tdesocketdevice.cpp:110
KNetwork::TDESocketBase::setError
void setError(SocketError error)
Sets the socket's error code.
Definition: tdesocketbase.cpp:155
KNetwork::TDEBufferedSocket
Buffered stream sockets.
Definition: kbufferedsocket.h:58
KNetwork::KResolver::setFlags
int setFlags(int flags)
Sets the flags.
Definition: kresolver.cpp:389
KNetwork::TDEServerSocket::bind
virtual bool bind()
Binds the socket to the addresses previously set with setAddress.
Definition: kserversocket.cpp:208
KNetwork::TDESocketBase::setSocketOptions
virtual bool setSocketOptions(int opts)
Set the given socket options.
Definition: tdesocketbase.cpp:65
KNetwork::TDESocketDevice::close
virtual void close()
Closes the socket.
Definition: tdesocketdevice.cpp:180
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::readyAccept
void readyAccept()
This signal is emitted whenever the socket is ready for accepting – i.e., there is at least one conn...
KNetwork::TDESocketDevice::localAddress
virtual TDESocketAddress localAddress() const
Returns this socket's local address.
Definition: tdesocketdevice.cpp:535

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
  •     tdecore
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  • tdeioslave
  •   http
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdecore by doxygen 1.8.8
This website is maintained by Timothy Pearson.