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 <sys/types.h>
00028
#include <sys/socket.h>
00029
00030
#include "ksocketaddress.h"
00031
#include "kresolver.h"
00032
#include "ksocketdevice.h"
00033
#include "kdatagramsocket.h"
00034
00035
using namespace KNetwork;
00036
00037 KDatagramSocket::KDatagramSocket(
QObject* parent,
const char *name)
00038 :
KClientSocketBase(parent, name), d(0L)
00039 {
00040
peerResolver().
setFamily(KResolver::KnownFamily);
00041
localResolver().
setFamily(KResolver::KnownFamily);
00042
00043
peerResolver().
setSocketType(SOCK_DGRAM);
00044
localResolver().
setSocketType(SOCK_DGRAM);
00045
00046
00047
00048 QObject::connect(&
peerResolver(), SIGNAL(finished(
KResolverResults)),
00049
this, SLOT(lookupFinishedPeer()));
00050 QObject::connect(
this, SIGNAL(
hostFound()),
this, SLOT(lookupFinishedLocal()));
00051 }
00052
00053 KDatagramSocket::~KDatagramSocket()
00054 {
00055
00056
00057
00058 }
00059
00060 bool KDatagramSocket::bind(
const QString& node,
const QString& service)
00061 {
00062
if (
state() >= Bound)
00063
return false;
00064
00065
if (
localResolver().
isRunning())
00066
localResolver().
cancel(
false);
00067
00068
00069
localResolver().
setAddress(node, service);
00070
00071
if (!
lookup())
00072
return false;
00073
00074
00075
00076
00077
if (
state() > HostLookup)
00078
return doBind();
00079
00080
return true;
00081 }
00082
00083 bool KDatagramSocket::connect(
const QString& node,
const QString& service)
00084 {
00085
if (
state() >= Connected)
00086
return true;
00087
00088
if (
peerResolver().
nodeName() != node ||
00089
peerResolver().
serviceName() != service)
00090
peerResolver().
setAddress(node, service);
00091
00092
00093
00094
00095 SocketState s =
state();
00096
setState(s == Connecting ? HostLookup : Idle);
00097
bool ok =
lookup();
00098
if (!ok)
00099 {
00100
setState(s);
00101
return false;
00102 }
00103
00104
00105
00106
if (
state() == HostLookup)
00107 {
00108
00109
setState(Connecting);
00110 emit
stateChanged(Connecting);
00111
return true;
00112 }
00113
00114
00115
if (
state() != Connected)
00116 {
00117
setState(Connecting);
00118 emit
stateChanged(Connecting);
00119 lookupFinishedPeer();
00120 }
00121
00122
return state() == Connected;
00123 }
00124
00125 KDatagramPacket KDatagramSocket::receive()
00126 {
00127 Q_LONG size =
bytesAvailable();
00128
if (size == 0)
00129 {
00130
00131
00132
if (
blocking())
00133
socketDevice()->
waitForMore(-1);
00134
else
00135 {
00136
00137
setError(IO_ReadError, WouldBlock);
00138 emit
gotError(WouldBlock);
00139
return KDatagramPacket();
00140 }
00141
00142
00143 size =
bytesAvailable();
00144 }
00145
00146
QByteArray data(size);
00147
KSocketAddress address;
00148
00149
00150 size =
readBlock(data.data(), size, address);
00151
if (size < 0)
00152
00153
return KDatagramPacket();
00154
00155 data.resize(size);
00156
return KDatagramPacket(data, address);
00157 }
00158
00159 Q_LONG
KDatagramSocket::send(
const KDatagramPacket& packet)
00160 {
00161
return writeBlock(packet.
data(), packet.
size(), packet.
address());
00162 }
00163
00164
void KDatagramSocket::lookupFinishedLocal()
00165 {
00166
00167
00168
00169
if (!doBind())
00170
return;
00171
00172
if (
peerResults().count() > 0)
00173 {
00174
setState(Connecting);
00175 emit
stateChanged(Connecting);
00176
00177 lookupFinishedPeer();
00178 }
00179 }
00180
00181
void KDatagramSocket::lookupFinishedPeer()
00182 {
00183
00184
00185
00186
00187
if (
state() != Connecting)
00188
return;
00189
00190
if (
peerResults().count() == 0)
00191 {
00192
setState(Unconnected);
00193 emit
stateChanged(Unconnected);
00194
return;
00195 }
00196
00197 KResolverResults::ConstIterator it =
peerResults().begin();
00198
for ( ; it !=
peerResults().end(); ++it)
00199
if (
connect(*it))
00200 {
00201
00202
setState(Connected);
00203 emit
stateChanged(Connected);
00204 emit
connected(*it);
00205
return;
00206 }
00207
00208
00209
copyError();
00210
setState(Unconnected);
00211 emit
stateChanged(Unconnected);
00212 emit
gotError(
error());
00213 }
00214
00215
bool KDatagramSocket::doBind()
00216 {
00217
if (
localResults().count() == 0)
00218
return true;
00219
if (
state() >= Bound)
00220
return true;
00221
00222 KResolverResults::ConstIterator it =
localResults().begin();
00223
for ( ; it !=
localResults().end(); ++it)
00224
if (
bind(*it))
00225 {
00226
00227
return true;
00228 }
00229
00230
00231
00232
copyError();
00233 emit
gotError(
error());
00234
return false;
00235 }
00236
00237
#include "kdatagramsocket.moc"