kserversocket.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <config.h>
00026
00027 #include <qsocketnotifier.h>
00028 #include <qmutex.h>
00029
00030 #include "ksocketaddress.h"
00031 #include "kresolver.h"
00032 #include "ksocketbase.h"
00033 #include "ksocketdevice.h"
00034 #include "kstreamsocket.h"
00035 #include "kbufferedsocket.h"
00036 #include "kserversocket.h"
00037
00038 using namespace KNetwork;
00039
00040 class KNetwork::KServerSocketPrivate
00041 {
00042 public:
00043 KResolver resolver;
00044 KResolverResults resolverResults;
00045
00046 enum { None, LookupDone, Bound, Listening } state;
00047 int backlog;
00048 int timeout;
00049
00050 bool bindWhenFound : 1, listenWhenBound : 1, useKBufferedSocket : 1;
00051
00052 KServerSocketPrivate()
00053 : state(None), timeout(0), bindWhenFound(false), listenWhenBound(false),
00054 useKBufferedSocket(true)
00055 {
00056 resolver.setFlags(KResolver::Passive);
00057 resolver.setFamily(KResolver::KnownFamily);
00058 }
00059 };
00060
00061 KServerSocket::KServerSocket(QObject* parent, const char *name)
00062 : QObject(parent, name), d(new KServerSocketPrivate)
00063 {
00064 QObject::connect(&d->resolver, SIGNAL(finished(KResolverResults)),
00065 this, SLOT(lookupFinishedSlot()));
00066 }
00067
00068 KServerSocket::KServerSocket(const QString& service, QObject* parent, const char *name)
00069 : QObject(parent, name), d(new KServerSocketPrivate)
00070 {
00071 QObject::connect(&d->resolver, SIGNAL(finished(KResolverResults)),
00072 this, SLOT(lookupFinishedSlot()));
00073 d->resolver.setServiceName(service);
00074 }
00075
00076 KServerSocket::KServerSocket(const QString& node, const QString& service,
00077 QObject* parent, const char* name)
00078 : QObject(parent, name), d(new KServerSocketPrivate)
00079 {
00080 QObject::connect(&d->resolver, SIGNAL(finished(KResolverResults)),
00081 this, SLOT(lookupFinishedSlot()));
00082 setAddress(node, service);
00083 }
00084
00085 KServerSocket::~KServerSocket()
00086 {
00087 close();
00088 delete d;
00089 }
00090
00091 bool KServerSocket::setSocketOptions(int opts)
00092 {
00093 QMutexLocker locker(mutex());
00094 KSocketBase::setSocketOptions(opts);
00095 bool result = socketDevice()->setSocketOptions(opts);
00096 copyError();
00097 return result;
00098 }
00099
00100 KResolver& KServerSocket::resolver() const
00101 {
00102 return d->resolver;
00103 }
00104
00105 const KResolverResults& KServerSocket::resolverResults() const
00106 {
00107 return d->resolverResults;
00108 }
00109
00110 void KServerSocket::setResolutionEnabled(bool enable)
00111 {
00112 if (enable)
00113 d->resolver.setFlags(d->resolver.flags() & ~KResolver::NoResolve);
00114 else
00115 d->resolver.setFlags(d->resolver.flags() | KResolver::NoResolve);
00116 }
00117
00118 void KServerSocket::setFamily(int families)
00119 {
00120 d->resolver.setFamily(families);
00121 }
00122
00123 void KServerSocket::setAddress(const QString& service)
00124 {
00125 d->resolver.setNodeName(QString::null);
00126 d->resolver.setServiceName(service);
00127 d->resolverResults.empty();
00128 }
00129
00130 void KServerSocket::setAddress(const QString& node, const QString& service)
00131 {
00132 d->resolver.setNodeName(node);
00133 d->resolver.setServiceName(service);
00134 d->resolverResults.empty();
00135 }
00136
00137 void KServerSocket::setTimeout(int msec)
00138 {
00139 d->timeout = msec;
00140 }
00141
00142 bool KServerSocket::lookup()
00143 {
00144 setError(NoError);
00145 if (d->resolver.isRunning() && !blocking())
00146 return true;
00147
00148 if (d->state >= KServerSocketPrivate::LookupDone)
00149 return true;
00150
00151
00152 if (d->resolver.serviceName().isNull() &&
00153 !d->resolver.nodeName().isNull())
00154 d->resolver.setServiceName(QString::fromLatin1(""));
00155
00156
00157
00158
00159
00160 d->resolverResults = KResolverResults();
00161
00162 if (d->resolver.status() <= 0)
00163
00164 d->resolver.start();
00165
00166 if (blocking())
00167 {
00168
00169
00170
00171 d->resolver.wait();
00172
00173 }
00174
00175 return true;
00176 }
00177
00178 bool KServerSocket::bind(const KResolverEntry& address)
00179 {
00180 if (socketDevice()->bind(address))
00181 {
00182 setError(NoError);
00183
00184 d->state = KServerSocketPrivate::Bound;
00185 emit bound(address);
00186 return true;
00187 }
00188 copyError();
00189 return false;
00190 }
00191
00192 bool KServerSocket::bind(const QString& node, const QString& service)
00193 {
00194 setAddress(node, service);
00195 return bind();
00196 }
00197
00198 bool KServerSocket::bind(const QString& service)
00199 {
00200 setAddress(service);
00201 return bind();
00202 }
00203
00204 bool KServerSocket::bind()
00205 {
00206 if (d->state >= KServerSocketPrivate::Bound)
00207 return true;
00208
00209 if (d->state < KServerSocketPrivate::LookupDone)
00210 {
00211 d->bindWhenFound = true;
00212 bool ok = lookup();
00213 if (d->state >= KServerSocketPrivate::Bound)
00214 d->bindWhenFound = false;
00215 return ok;
00216 }
00217
00218 if (!doBind())
00219 {
00220 setError(NotSupported);
00221 emit gotError(NotSupported);
00222 return false;
00223 }
00224
00225 return true;;
00226 }
00227
00228 bool KServerSocket::listen(int backlog)
00229 {
00230
00231
00232
00233
00234
00235 if (d->state == KServerSocketPrivate::Listening)
00236 return true;
00237
00238 if (d->state < KServerSocketPrivate::Bound)
00239 {
00240
00241
00242 d->listenWhenBound = true;
00243 d->backlog = backlog;
00244 if (!bind())
00245 {
00246 d->listenWhenBound = false;
00247 return false;
00248 }
00249
00250 if (d->state < KServerSocketPrivate::Bound)
00251
00252
00253 return true;
00254
00255 d->listenWhenBound = false;
00256 }
00257
00258 if (d->state < KServerSocketPrivate::Listening)
00259 {
00260 if (!socketDevice()->listen(backlog))
00261 {
00262 copyError();
00263 emit gotError(error());
00264 return false;
00265 }
00266
00267
00268 QObject::connect(socketDevice()->readNotifier(), SIGNAL(activated(int)),
00269 this, SIGNAL(readyAccept()));
00270 d->state = KServerSocketPrivate::Listening;
00271 return true;
00272 }
00273
00274 return true;
00275 }
00276
00277 void KServerSocket::close()
00278 {
00279 socketDevice()->close();
00280 if (d->resolver.isRunning())
00281 d->resolver.cancel(false);
00282 d->state = KServerSocketPrivate::None;
00283 emit closed();
00284 }
00285
00286 void KServerSocket::setAcceptBuffered(bool enable)
00287 {
00288 d->useKBufferedSocket = enable;
00289 }
00290
00291 KActiveSocketBase* KServerSocket::accept()
00292 {
00293 if (d->state < KServerSocketPrivate::Listening)
00294 {
00295 if (!blocking())
00296 {
00297 listen();
00298 setError(WouldBlock);
00299 return NULL;
00300 }
00301 else if (!listen())
00302
00303 return false;
00304 }
00305
00306
00307 if (blocking() && d->timeout > 0)
00308 {
00309 bool timedout;
00310 if (!socketDevice()->poll(d->timeout, &timedout))
00311 {
00312 copyError();
00313 return NULL;
00314 }
00315
00316 if (timedout)
00317 return 0L;
00318 }
00319
00320
00321 KSocketDevice* accepted = socketDevice()->accept();
00322 if (!accepted)
00323 {
00324
00325 copyError();
00326 return NULL;
00327 }
00328
00329 KStreamSocket* streamsocket;
00330 if (d->useKBufferedSocket)
00331 streamsocket = new KBufferedSocket();
00332 else
00333 streamsocket = new KStreamSocket();
00334 streamsocket->setSocketDevice(accepted);
00335
00336
00337
00338
00339 streamsocket->setState(KStreamSocket::Connected);
00340 streamsocket->setFlags(IO_Sequential | IO_Raw | IO_ReadWrite | IO_Open | IO_Async);
00341
00342 return streamsocket;
00343 }
00344
00345 KSocketAddress KServerSocket::localAddress() const
00346 {
00347 return socketDevice()->localAddress();
00348 }
00349
00350 KSocketAddress KServerSocket::externalAddress() const
00351 {
00352 return socketDevice()->externalAddress();
00353 }
00354
00355 void KServerSocket::lookupFinishedSlot()
00356 {
00357 if (d->resolver.isRunning() || d->state > KServerSocketPrivate::LookupDone)
00358 return;
00359
00360 if (d->resolver.status() < 0)
00361 {
00362 setError(LookupFailure);
00363 emit gotError(LookupFailure);
00364 d->bindWhenFound = d->listenWhenBound = false;
00365 d->state = KServerSocketPrivate::None;
00366 return;
00367 }
00368
00369
00370 d->resolverResults = d->resolver.results();
00371 d->state = KServerSocketPrivate::LookupDone;
00372 emit hostFound();
00373
00374 if (d->bindWhenFound)
00375 doBind();
00376 }
00377
00378 void KServerSocket::copyError()
00379 {
00380 setError(socketDevice()->error());
00381 }
00382
00383 bool KServerSocket::doBind()
00384 {
00385 d->bindWhenFound = false;
00386
00387
00388 KResolverResults::ConstIterator it = d->resolverResults.begin();
00389 for ( ; it != d->resolverResults.end(); ++it)
00390 if (bind(*it))
00391 {
00392 if (d->listenWhenBound)
00393 listen(d->backlog);
00394 return true;
00395 }
00396
00397
00398 emit gotError(error());
00399 return false;
00400 }
00401
00402 #include "kserversocket.moc"
This file is part of the documentation for kdecore Library Version 3.3.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Thu Sep 23 17:11:37 2004 by
doxygen 1.3.8-20040913 written by
Dimitri van Heesch, © 1997-2003