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"