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 <qtimer.h>
00029
#include <qmutex.h>
00030
00031
#include "ksocketaddress.h"
00032
#include "kresolver.h"
00033
#include "ksocketbase.h"
00034
#include "ksocketdevice.h"
00035
#include "kclientsocketbase.h"
00036
00037
using namespace KNetwork;
00038
00039
class KNetwork::KClientSocketBasePrivate
00040 {
00041
public:
00042
int state;
00043
00044
KResolver localResolver, peerResolver;
00045
KResolverResults localResults, peerResults;
00046
00047
bool enableRead : 1, enableWrite : 1;
00048 };
00049
00050 KClientSocketBase::KClientSocketBase(
QObject *parent,
const char *name)
00051 :
QObject(parent, name), d(new KClientSocketBasePrivate)
00052 {
00053 d->state = Idle;
00054 d->enableRead =
true;
00055 d->enableWrite =
false;
00056 }
00057
00058 KClientSocketBase::~KClientSocketBase()
00059 {
00060
close();
00061
delete d;
00062 }
00063
00064 KClientSocketBase::SocketState
KClientSocketBase::state()
const
00065
{
00066
return static_cast<SocketState>(d->state);
00067 }
00068
00069 void KClientSocketBase::setState(SocketState state)
00070 {
00071 d->state = state;
00072
stateChanging(state);
00073 }
00074
00075 bool KClientSocketBase::setSocketOptions(
int opts)
00076 {
00077
QMutexLocker locker(
mutex());
00078
KSocketBase::setSocketOptions(opts);
00079
00080
00081
if (
hasDevice())
00082 {
00083
bool result =
socketDevice()->
setSocketOptions(opts);
00084
copyError();
00085
return result;
00086 }
00087
00088
return true;
00089 }
00090
00091 KResolver&
KClientSocketBase::peerResolver()
const
00092
{
00093
return d->peerResolver;
00094 }
00095
00096 const KResolverResults&
KClientSocketBase::peerResults()
const
00097
{
00098
return d->peerResults;
00099 }
00100
00101 KResolver&
KClientSocketBase::localResolver()
const
00102
{
00103
return d->localResolver;
00104 }
00105
00106 const KResolverResults&
KClientSocketBase::localResults()
const
00107
{
00108
return d->localResults;
00109 }
00110
00111 void KClientSocketBase::setResolutionEnabled(
bool enable)
00112 {
00113
if (enable)
00114 {
00115 d->localResolver.setFlags(d->localResolver.flags() & ~
KResolver::NoResolve);
00116 d->peerResolver.setFlags(d->peerResolver.flags() & ~
KResolver::NoResolve);
00117 }
00118
else
00119 {
00120 d->localResolver.setFlags(d->localResolver.flags() | KResolver::NoResolve);
00121 d->peerResolver.setFlags(d->peerResolver.flags() | KResolver::NoResolve);
00122 }
00123 }
00124
00125 void KClientSocketBase::setFamily(
int families)
00126 {
00127 d->localResolver.setFamily(families);
00128 d->peerResolver.setFamily(families);
00129 }
00130
00131 bool KClientSocketBase::lookup()
00132 {
00133
if (
state() == HostLookup && !
blocking())
00134
return true;
00135
00136
if (
state() > HostLookup)
00137
return true;
00138
00139
if (
state() < HostLookup)
00140 {
00141
if (d->localResolver.serviceName().isNull() &&
00142 !d->localResolver.nodeName().isNull())
00143 d->localResolver.setServiceName(QString::fromLatin1(
""));
00144
00145
00146
00147 QObject::connect(&d->peerResolver, SIGNAL(finished(
KResolverResults)),
00148
this, SLOT(lookupFinishedSlot()));
00149 QObject::connect(&d->localResolver, SIGNAL(finished(
KResolverResults)),
00150
this, SLOT(lookupFinishedSlot()));
00151
00152
if (d->localResolver.status() <= 0)
00153 d->localResolver.start();
00154
if (d->peerResolver.status() <= 0)
00155 d->peerResolver.start();
00156
00157
setState(HostLookup);
00158 emit
stateChanged(HostLookup);
00159
00160
if (!d->localResolver.isRunning() && !d->peerResolver.isRunning())
00161 {
00162
00163
00164
if (
blocking())
00165 lookupFinishedSlot();
00166
else
00167 QTimer::singleShot(0,
this, SLOT(lookupFinishedSlot()));
00168 }
00169
else
00170 {
00171 d->localResults = d->peerResults =
KResolverResults();
00172 }
00173 }
00174
00175
if (
blocking())
00176 {
00177
00178
00179
00180
localResolver().
wait();
00181
peerResolver().
wait();
00182
00183
00184 }
00185
00186
return true;
00187 }
00188
00189 bool KClientSocketBase::bind(
const KResolverEntry& address)
00190 {
00191
if (
state() == HostLookup ||
state() > Connecting)
00192
return false;
00193
00194
if (
socketDevice()->
bind(address))
00195 {
00196
resetError();
00197
00198
00199
if (
state() < Bound)
00200 {
00201
setState(Bound);
00202 emit
stateChanged(Bound);
00203 emit
bound(address);
00204 }
00205
return true;
00206 }
00207
return false;
00208 }
00209
00210 bool KClientSocketBase::connect(
const KResolverEntry& address)
00211 {
00212
if (
state() == Connected)
00213
return true;
00214
if (
state() == HostLookup ||
state() > Connecting)
00215
return false;
00216
00217
bool ok =
socketDevice()->
connect(address);
00218
copyError();
00219
00220
if (ok)
00221 {
00222
SocketState newstate;
00223
if (
error() == InProgress)
00224 newstate = Connecting;
00225
else
00226 newstate = Connected;
00227
00228
if (
state() < newstate)
00229 {
00230
setState(newstate);
00231 emit
stateChanged(newstate);
00232
if (
error() == NoError)
00233 {
00234 setFlags(IO_Sequential | IO_Raw | IO_ReadWrite | IO_Open | IO_Async);
00235 emit
connected(address);
00236 }
00237 }
00238
00239
return true;
00240 }
00241
return false;
00242 }
00243
00244 bool KClientSocketBase::disconnect()
00245 {
00246
if (
state() != Connected)
00247
return false;
00248
00249
bool ok =
socketDevice()->
disconnect();
00250
copyError();
00251
00252
if (ok)
00253 {
00254
setState(Unconnected);
00255 emit
stateChanged(Unconnected);
00256
return true;
00257 }
00258
return false;
00259 }
00260
00261 void KClientSocketBase::close()
00262 {
00263
if (
state() == Idle)
00264
return;
00265
00266
if (
state() == HostLookup)
00267 {
00268 d->peerResolver.cancel(
false);
00269 d->localResolver.cancel(
false);
00270 }
00271
00272 d->localResults = d->peerResults =
KResolverResults();
00273
00274
socketDevice()->
close();
00275
setState(Idle);
00276 emit
stateChanged(Idle);
00277 emit
closed();
00278 }
00279
00280 Q_LONG
KClientSocketBase::bytesAvailable()
const
00281
{
00282
return socketDevice()->
bytesAvailable();
00283 }
00284
00285 Q_LONG
KClientSocketBase::waitForMore(
int msecs,
bool *timeout)
00286 {
00287
return socketDevice()->
waitForMore(msecs, timeout);
00288 }
00289
00290 Q_LONG
KClientSocketBase::readBlock(
char *data, Q_ULONG maxlen)
00291 {
00292
return socketDevice()->
readBlock(data, maxlen);
00293 }
00294
00295 Q_LONG
KClientSocketBase::readBlock(
char *data, Q_ULONG maxlen,
KSocketAddress& from)
00296 {
00297
return socketDevice()->
readBlock(data, maxlen, from);
00298 }
00299
00300 Q_LONG
KClientSocketBase::peekBlock(
char *data, Q_ULONG maxlen)
00301 {
00302
return socketDevice()->
peekBlock(data, maxlen);
00303 }
00304
00305 Q_LONG
KClientSocketBase::peekBlock(
char *data, Q_ULONG maxlen,
KSocketAddress& from)
00306 {
00307
return socketDevice()->
peekBlock(data, maxlen, from);
00308 }
00309
00310 Q_LONG
KClientSocketBase::writeBlock(
const char *data, Q_ULONG len)
00311 {
00312
return socketDevice()->
writeBlock(data, len);
00313 }
00314
00315 Q_LONG
KClientSocketBase::writeBlock(
const char *data, Q_ULONG len,
const KSocketAddress& to)
00316 {
00317
return socketDevice()->
writeBlock(data, len, to);
00318 }
00319
00320 KSocketAddress KClientSocketBase::localAddress()
const
00321
{
00322
return socketDevice()->
localAddress();
00323 }
00324
00325 KSocketAddress KClientSocketBase::peerAddress()
const
00326
{
00327
return socketDevice()->
peerAddress();
00328 }
00329
00330 bool KClientSocketBase::emitsReadyRead()
const
00331
{
00332
return d->enableRead;
00333 }
00334
00335 void KClientSocketBase::enableRead(
bool enable)
00336 {
00337
QMutexLocker locker(
mutex());
00338
00339 d->enableRead = enable;
00340
QSocketNotifier *n =
socketDevice()->
readNotifier();
00341
if (n)
00342 n->setEnabled(enable);
00343 }
00344
00345 bool KClientSocketBase::emitsReadyWrite()
const
00346
{
00347
return d->enableWrite;
00348 }
00349
00350 void KClientSocketBase::enableWrite(
bool enable)
00351 {
00352
QMutexLocker locker(
mutex());
00353
00354 d->enableWrite = enable;
00355
QSocketNotifier *n =
socketDevice()->
writeNotifier();
00356
if (n)
00357 n->setEnabled(enable);
00358 }
00359
00360 void KClientSocketBase::slotReadActivity()
00361 {
00362
if (d->enableRead)
00363 emit
readyRead();
00364 }
00365
00366 void KClientSocketBase::slotWriteActivity()
00367 {
00368
if (d->enableWrite)
00369 emit
readyWrite();
00370 }
00371
00372
void KClientSocketBase::lookupFinishedSlot()
00373 {
00374
if (d->peerResolver.isRunning() || d->localResolver.isRunning() ||
state() != HostLookup)
00375
return;
00376
00377 QObject::disconnect(&d->peerResolver, 0L,
this, SLOT(lookupFinishedSlot()));
00378 QObject::disconnect(&d->localResolver, 0L,
this, SLOT(lookupFinishedSlot()));
00379
if (d->peerResolver.status() < 0 || d->localResolver.status() < 0)
00380 {
00381
setState(Idle);
00382
setError(IO_LookupError, LookupFailure);
00383 emit
stateChanged(Idle);
00384 emit
gotError(LookupFailure);
00385
return;
00386 }
00387
00388 d->localResults = d->localResolver.results();
00389 d->peerResults = d->peerResolver.results();
00390
setState(HostFound);
00391 emit
stateChanged(HostFound);
00392 emit
hostFound();
00393 }
00394
00395 void KClientSocketBase::stateChanging(SocketState newState)
00396 {
00397
if (newState == Connected &&
socketDevice())
00398 {
00399
QSocketNotifier *n =
socketDevice()->
readNotifier();
00400
if (n)
00401 {
00402 n->setEnabled(d->enableRead);
00403 QObject::connect(n, SIGNAL(activated(
int)),
this, SLOT(
slotReadActivity()));
00404 }
00405
else
00406
return;
00407
00408 n =
socketDevice()->
writeNotifier();
00409
if (n)
00410 {
00411 n->setEnabled(d->enableWrite);
00412 QObject::connect(n, SIGNAL(activated(
int)),
this, SLOT(
slotWriteActivity()));
00413 }
00414
else
00415
return;
00416 }
00417 }
00418
00419 void KClientSocketBase::copyError()
00420 {
00421
setError(
socketDevice()->status(),
socketDevice()->
error());
00422 }
00423
00424
#include "kclientsocketbase.moc"