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 <tqsocketnotifier.h>
00028 #include <tqtimer.h>
00029 #include <tqmutex.h>
00030
00031 #include "tdesocketaddress.h"
00032 #include "kresolver.h"
00033 #include "tdesocketbase.h"
00034 #include "tdesocketdevice.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(TQObject *parent, const char *name) :
00051 #ifdef USE_QT4
00052 #else
00053 TQObject(parent, name),
00054 #endif
00055 d(new KClientSocketBasePrivate)
00056 {
00057 #ifdef USE_QT4
00058 setParent(parent);
00059 setObjectName(name);
00060 #endif // USE_QT4
00061 d->state = Idle;
00062 d->enableRead = true;
00063 d->enableWrite = false;
00064 }
00065
00066 KClientSocketBase::~KClientSocketBase()
00067 {
00068 close();
00069 delete d;
00070 }
00071
00072 KClientSocketBase::SocketState KClientSocketBase::state() const
00073 {
00074 return static_cast<SocketState>(d->state);
00075 }
00076
00077 void KClientSocketBase::setState(SocketState state)
00078 {
00079 d->state = state;
00080 stateChanging(state);
00081 }
00082
00083 bool KClientSocketBase::setSocketOptions(int opts)
00084 {
00085 TQMutexLocker locker(mutex());
00086 TDESocketBase::setSocketOptions(opts);
00087
00088
00089 if (hasDevice())
00090 {
00091 bool result = socketDevice()->setSocketOptions(opts);
00092 copyError();
00093 return result;
00094 }
00095
00096 return true;
00097 }
00098
00099 KResolver& KClientSocketBase::peerResolver() const
00100 {
00101 return d->peerResolver;
00102 }
00103
00104 const KResolverResults& KClientSocketBase::peerResults() const
00105 {
00106 return d->peerResults;
00107 }
00108
00109 KResolver& KClientSocketBase::localResolver() const
00110 {
00111 return d->localResolver;
00112 }
00113
00114 const KResolverResults& KClientSocketBase::localResults() const
00115 {
00116 return d->localResults;
00117 }
00118
00119 void KClientSocketBase::setResolutionEnabled(bool enable)
00120 {
00121 if (enable)
00122 {
00123 d->localResolver.setFlags(d->localResolver.flags() & ~KResolver::NoResolve);
00124 d->peerResolver.setFlags(d->peerResolver.flags() & ~KResolver::NoResolve);
00125 }
00126 else
00127 {
00128 d->localResolver.setFlags(d->localResolver.flags() | KResolver::NoResolve);
00129 d->peerResolver.setFlags(d->peerResolver.flags() | KResolver::NoResolve);
00130 }
00131 }
00132
00133 void KClientSocketBase::setFamily(int families)
00134 {
00135 d->localResolver.setFamily(families);
00136 d->peerResolver.setFamily(families);
00137 }
00138
00139 bool KClientSocketBase::lookup()
00140 {
00141 if (state() == HostLookup && !blocking())
00142 return true;
00143
00144 if (state() > HostLookup)
00145 return true;
00146
00147 if (state() < HostLookup)
00148 {
00149 if (d->localResolver.serviceName().isNull() &&
00150 !d->localResolver.nodeName().isNull())
00151 d->localResolver.setServiceName(TQString::fromLatin1(""));
00152
00153
00154
00155 TQObject::connect(&d->peerResolver, TQT_SIGNAL(finished(KResolverResults)),
00156 this, TQT_SLOT(lookupFinishedSlot()));
00157 TQObject::connect(&d->localResolver, TQT_SIGNAL(finished(KResolverResults)),
00158 this, TQT_SLOT(lookupFinishedSlot()));
00159
00160 if (d->localResolver.status() <= 0)
00161 d->localResolver.start();
00162 if (d->peerResolver.status() <= 0)
00163 d->peerResolver.start();
00164
00165 setState(HostLookup);
00166 emit stateChanged(HostLookup);
00167
00168 if (!d->localResolver.isRunning() && !d->peerResolver.isRunning())
00169 {
00170
00171
00172 if (blocking())
00173 lookupFinishedSlot();
00174 else
00175 TQTimer::singleShot(0, this, TQT_SLOT(lookupFinishedSlot()));
00176 }
00177 else
00178 {
00179 d->localResults = d->peerResults = KResolverResults();
00180 }
00181 }
00182
00183 if (blocking())
00184 {
00185
00186
00187
00188 localResolver().wait();
00189 peerResolver().wait();
00190
00191
00192 }
00193
00194 return true;
00195 }
00196
00197 bool KClientSocketBase::bind(const KResolverEntry& address)
00198 {
00199 if (state() == HostLookup || state() > Connecting)
00200 return false;
00201
00202 if (socketDevice()->bind(address))
00203 {
00204 resetError();
00205
00206
00207 if (state() < Bound)
00208 {
00209 setState(Bound);
00210 emit stateChanged(Bound);
00211 emit bound(address);
00212 }
00213 return true;
00214 }
00215 return false;
00216 }
00217
00218 bool KClientSocketBase::connect(const KResolverEntry& address)
00219 {
00220 if (state() == Connected)
00221 return true;
00222 if (state() == HostLookup || state() > Connecting)
00223 return false;
00224
00225 bool ok = socketDevice()->connect(address);
00226 copyError();
00227
00228 if (ok)
00229 {
00230 SocketState newstate;
00231 if (error() == InProgress)
00232 newstate = Connecting;
00233 else
00234 newstate = Connected;
00235
00236 if (state() < newstate)
00237 {
00238 setState(newstate);
00239 emit stateChanged(newstate);
00240 if (error() == NoError)
00241 {
00242 setFlags(IO_Sequential | IO_Raw | IO_ReadWrite | IO_Open | IO_Async);
00243 emit connected(address);
00244 }
00245 }
00246
00247 return true;
00248 }
00249 return false;
00250 }
00251
00252 bool KClientSocketBase::disconnect()
00253 {
00254 if (state() != Connected)
00255 return false;
00256
00257 bool ok = socketDevice()->disconnect();
00258 copyError();
00259
00260 if (ok)
00261 {
00262 setState(Unconnected);
00263 emit stateChanged(Unconnected);
00264 return true;
00265 }
00266 return false;
00267 }
00268
00269 void KClientSocketBase::close()
00270 {
00271 if (state() == Idle)
00272 return;
00273
00274 if (state() == HostLookup)
00275 {
00276 d->peerResolver.cancel(false);
00277 d->localResolver.cancel(false);
00278 }
00279
00280 d->localResults = d->peerResults = KResolverResults();
00281
00282 socketDevice()->close();
00283 setState(Idle);
00284 emit stateChanged(Idle);
00285 emit closed();
00286 }
00287
00288
00289 #ifdef USE_QT3
00290 TQ_LONG KClientSocketBase::bytesAvailable() const
00291 #endif
00292 #ifdef USE_QT4
00293 qint64 KClientSocketBase::bytesAvailable() const
00294 #endif
00295 {
00296 return socketDevice()->bytesAvailable();
00297 }
00298
00299
00300
00301
00302 TQ_LONG KClientSocketBase::waitForMore(int msecs, bool *timeout)
00303 {
00304 resetError();
00305 TQ_LONG retval = socketDevice()->waitForMore(msecs, timeout);
00306 if (retval == -1)
00307 {
00308 copyError();
00309 emit gotError(error());
00310 }
00311 return retval;
00312 }
00313
00314 TQT_TQIO_LONG KClientSocketBase::tqreadBlock(char *data, TQT_TQIO_ULONG maxlen)
00315 {
00316 resetError();
00317 TQ_LONG retval = socketDevice()->tqreadBlock(data, maxlen);
00318 if (retval == -1)
00319 {
00320 copyError();
00321 emit gotError(error());
00322 }
00323 return retval;
00324 }
00325
00326 TQT_TQIO_LONG KClientSocketBase::tqreadBlock(char *data, TQT_TQIO_ULONG maxlen, TDESocketAddress& from)
00327 {
00328 resetError();
00329 TQ_LONG retval = socketDevice()->tqreadBlock(data, maxlen, from);
00330 if (retval == -1)
00331 {
00332 copyError();
00333 emit gotError(error());
00334 }
00335 return retval;
00336 }
00337
00338 TQ_LONG KClientSocketBase::peekBlock(char *data, TQ_ULONG maxlen)
00339 {
00340 resetError();
00341 TQ_LONG retval = socketDevice()->peekBlock(data, maxlen);
00342 if (retval == -1)
00343 {
00344 copyError();
00345 emit gotError(error());
00346 }
00347 return retval;
00348 }
00349
00350 TQ_LONG KClientSocketBase::peekBlock(char *data, TQ_ULONG maxlen, TDESocketAddress& from)
00351 {
00352 resetError();
00353 TQ_LONG retval = socketDevice()->peekBlock(data, maxlen, from);
00354 if (retval == -1)
00355 {
00356 copyError();
00357 emit gotError(error());
00358 }
00359 return retval;
00360 }
00361
00362 TQT_TQIO_LONG KClientSocketBase::tqwriteBlock(const char *data, TQT_TQIO_ULONG len)
00363 {
00364 resetError();
00365 TQ_LONG retval = socketDevice()->tqwriteBlock(data, len);
00366 if (retval == -1)
00367 {
00368 copyError();
00369 emit gotError(error());
00370 }
00371 return retval;
00372 }
00373
00374 TQT_TQIO_LONG KClientSocketBase::tqwriteBlock(const char *data, TQT_TQIO_ULONG len, const TDESocketAddress& to)
00375 {
00376 resetError();
00377 TQ_LONG retval = socketDevice()->tqwriteBlock(data, len, to);
00378 if (retval == -1)
00379 {
00380 copyError();
00381 emit gotError(error());
00382 }
00383 return retval;
00384 }
00385
00386 TDESocketAddress KClientSocketBase::localAddress() const
00387 {
00388 return socketDevice()->localAddress();
00389 }
00390
00391 TDESocketAddress KClientSocketBase::peerAddress() const
00392 {
00393 return socketDevice()->peerAddress();
00394 }
00395
00396 bool KClientSocketBase::emitsReadyRead() const
00397 {
00398 return d->enableRead;
00399 }
00400
00401 void KClientSocketBase::enableRead(bool enable)
00402 {
00403 TQMutexLocker locker(mutex());
00404
00405 d->enableRead = enable;
00406 TQSocketNotifier *n = socketDevice()->readNotifier();
00407 if (n)
00408 n->setEnabled(enable);
00409 }
00410
00411 bool KClientSocketBase::emitsReadyWrite() const
00412 {
00413 return d->enableWrite;
00414 }
00415
00416 void KClientSocketBase::enableWrite(bool enable)
00417 {
00418 TQMutexLocker locker(mutex());
00419
00420 d->enableWrite = enable;
00421 TQSocketNotifier *n = socketDevice()->writeNotifier();
00422 if (n)
00423 n->setEnabled(enable);
00424 }
00425
00426 void KClientSocketBase::slotReadActivity()
00427 {
00428 if (d->enableRead)
00429 emit readyRead();
00430 }
00431
00432 void KClientSocketBase::slotWriteActivity()
00433 {
00434 if (d->enableWrite)
00435 emit readyWrite();
00436 }
00437
00438 void KClientSocketBase::lookupFinishedSlot()
00439 {
00440 if (d->peerResolver.isRunning() || d->localResolver.isRunning() || state() != HostLookup)
00441 return;
00442
00443 TQObject::disconnect(&d->peerResolver, 0L, this, TQT_SLOT(lookupFinishedSlot()));
00444 TQObject::disconnect(&d->localResolver, 0L, this, TQT_SLOT(lookupFinishedSlot()));
00445 if (d->peerResolver.status() < 0 || d->localResolver.status() < 0)
00446 {
00447 setState(Idle);
00448 setError(IO_LookupError, LookupFailure);
00449 emit stateChanged(Idle);
00450 emit gotError(LookupFailure);
00451 return;
00452 }
00453
00454 d->localResults = d->localResolver.results();
00455 d->peerResults = d->peerResolver.results();
00456 setState(HostFound);
00457 emit stateChanged(HostFound);
00458 emit hostFound();
00459 }
00460
00461 void KClientSocketBase::stateChanging(SocketState newState)
00462 {
00463 if (newState == Connected && socketDevice())
00464 {
00465 TQSocketNotifier *n = socketDevice()->readNotifier();
00466 if (n)
00467 {
00468 n->setEnabled(d->enableRead);
00469 TQObject::connect(n, TQT_SIGNAL(activated(int)), this, TQT_SLOT(slotReadActivity()));
00470 }
00471 else
00472 return;
00473
00474 n = socketDevice()->writeNotifier();
00475 if (n)
00476 {
00477 n->setEnabled(d->enableWrite);
00478 TQObject::connect(n, TQT_SIGNAL(activated(int)), this, TQT_SLOT(slotWriteActivity()));
00479 }
00480 else
00481 return;
00482 }
00483 }
00484
00485 void KClientSocketBase::copyError()
00486 {
00487 setError(socketDevice()->status(), socketDevice()->error());
00488 }
00489
00490 #include "kclientsocketbase.moc"