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"