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 if (d->state <= KServerSocketPrivate::LookupDone)
00129 d->state = KServerSocketPrivate::None;
00130 }
00131
00132 void KServerSocket::setAddress(const QString& node, const QString& service)
00133 {
00134 d->resolver.setNodeName(node);
00135 d->resolver.setServiceName(service);
00136 d->resolverResults.empty();
00137 if (d->state <= KServerSocketPrivate::LookupDone)
00138 d->state = KServerSocketPrivate::None;
00139 }
00140
00141 void KServerSocket::setTimeout(int msec)
00142 {
00143 d->timeout = msec;
00144 }
00145
00146 bool KServerSocket::lookup()
00147 {
00148 setError(NoError);
00149 if (d->resolver.isRunning() && !blocking())
00150 return true;
00151
00152 if (d->state >= KServerSocketPrivate::LookupDone)
00153 return true;
00154
00155
00156 if (d->resolver.serviceName().isNull() &&
00157 !d->resolver.nodeName().isNull())
00158 d->resolver.setServiceName(QString::fromLatin1(""));
00159
00160
00161
00162
00163
00164 d->resolverResults = KResolverResults();
00165
00166 if (d->resolver.status() <= 0)
00167
00168 d->resolver.start();
00169
00170 if (blocking())
00171 {
00172
00173
00174
00175 d->resolver.wait();
00176
00177 }
00178
00179 return true;
00180 }
00181
00182 bool KServerSocket::bind(const KResolverEntry& address)
00183 {
00184 if (socketDevice()->bind(address))
00185 {
00186 setError(NoError);
00187
00188 d->state = KServerSocketPrivate::Bound;
00189 emit bound(address);
00190 return true;
00191 }
00192 copyError();
00193 return false;
00194 }
00195
00196 bool KServerSocket::bind(const QString& node, const QString& service)
00197 {
00198 setAddress(node, service);
00199 return bind();
00200 }
00201
00202 bool KServerSocket::bind(const QString& service)
00203 {
00204 setAddress(service);
00205 return bind();
00206 }
00207
00208 bool KServerSocket::bind()
00209 {
00210 if (d->state >= KServerSocketPrivate::Bound)
00211 return true;
00212
00213 if (d->state < KServerSocketPrivate::LookupDone)
00214 {
00215 if (!blocking())
00216 {
00217 d->bindWhenFound = true;
00218 bool ok = lookup();
00219 if (d->state >= KServerSocketPrivate::Bound)
00220 d->bindWhenFound = false;
00221 return ok;
00222 }
00223
00224
00225 if (!lookup())
00226 return false;
00227 }
00228
00229 return doBind();
00230 }
00231
00232 bool KServerSocket::listen(int backlog)
00233 {
00234
00235
00236
00237
00238
00239 if (d->state == KServerSocketPrivate::Listening)
00240 return true;
00241
00242 d->backlog = backlog;
00243
00244 if (d->state < KServerSocketPrivate::Bound)
00245 {
00246
00247
00248 d->listenWhenBound = true;
00249 if (!bind())
00250 {
00251 d->listenWhenBound = false;
00252 return false;
00253 }
00254
00255 if (d->state < KServerSocketPrivate::Bound)
00256
00257
00258 return true;
00259
00260 d->listenWhenBound = false;
00261 }
00262
00263 if (d->state < KServerSocketPrivate::Listening)
00264 return doListen();
00265
00266 return true;
00267 }
00268
00269 void KServerSocket::close()
00270 {
00271 socketDevice()->close();
00272 if (d->resolver.isRunning())
00273 d->resolver.cancel(false);
00274 d->state = KServerSocketPrivate::None;
00275 emit closed();
00276 }
00277
00278 void KServerSocket::setAcceptBuffered(bool enable)
00279 {
00280 d->useKBufferedSocket = enable;
00281 }
00282
00283 KActiveSocketBase* KServerSocket::accept()
00284 {
00285 if (d->state < KServerSocketPrivate::Listening)
00286 {
00287 if (!blocking())
00288 {
00289 listen();
00290 setError(WouldBlock);
00291 return NULL;
00292 }
00293 else if (!listen())
00294
00295 return false;
00296 }
00297
00298
00299 if (blocking() && d->timeout > 0)
00300 {
00301 bool timedout;
00302 if (!socketDevice()->poll(d->timeout, &timedout))
00303 {
00304 copyError();
00305 return NULL;
00306 }
00307
00308 if (timedout)
00309 return 0L;
00310 }
00311
00312
00313 KSocketDevice* accepted = socketDevice()->accept();
00314 if (!accepted)
00315 {
00316
00317 copyError();
00318 return NULL;
00319 }
00320
00321 KStreamSocket* streamsocket;
00322 if (d->useKBufferedSocket)
00323 streamsocket = new KBufferedSocket();
00324 else
00325 streamsocket = new KStreamSocket();
00326 streamsocket->setSocketDevice(accepted);
00327
00328
00329
00330
00331 streamsocket->setState(KStreamSocket::Connected);
00332 streamsocket->setFlags(IO_Sequential | IO_Raw | IO_ReadWrite | IO_Open | IO_Async);
00333
00334 return streamsocket;
00335 }
00336
00337 KSocketAddress KServerSocket::localAddress() const
00338 {
00339 return socketDevice()->localAddress();
00340 }
00341
00342 KSocketAddress KServerSocket::externalAddress() const
00343 {
00344 return socketDevice()->externalAddress();
00345 }
00346
00347 void KServerSocket::lookupFinishedSlot()
00348 {
00349 if (d->resolver.isRunning() || d->state > KServerSocketPrivate::LookupDone)
00350 return;
00351
00352 if (d->resolver.status() < 0)
00353 {
00354 setError(LookupFailure);
00355 emit gotError(LookupFailure);
00356 d->bindWhenFound = d->listenWhenBound = false;
00357 d->state = KServerSocketPrivate::None;
00358 return;
00359 }
00360
00361
00362 d->resolverResults = d->resolver.results();
00363 d->state = KServerSocketPrivate::LookupDone;
00364 emit hostFound();
00365
00366 if (d->bindWhenFound)
00367 doBind();
00368 }
00369
00370 void KServerSocket::copyError()
00371 {
00372 setError(socketDevice()->error());
00373 }
00374
00375 bool KServerSocket::doBind()
00376 {
00377 d->bindWhenFound = false;
00378
00379
00380 KResolverResults::ConstIterator it = d->resolverResults.begin();
00381 for ( ; it != d->resolverResults.end(); ++it)
00382 if (bind(*it))
00383 {
00384 if (d->listenWhenBound)
00385 return doListen();
00386 return true;
00387 }
00388 else
00389 socketDevice()->close();
00390
00391
00392 emit gotError(error());
00393 return false;
00394 }
00395
00396 bool KServerSocket::doListen()
00397 {
00398 if (!socketDevice()->listen(d->backlog))
00399 {
00400 copyError();
00401 emit gotError(error());
00402 return false;
00403 }
00404
00405
00406 QObject::connect(socketDevice()->readNotifier(), SIGNAL(activated(int)),
00407 this, SIGNAL(readyAccept()));
00408 d->state = KServerSocketPrivate::Listening;
00409 return true;
00410 }
00411
00412
00413 #include "kserversocket.moc"