• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • tdecore
 

tdecore

  • tdecore
  • network
kdatagramsocket.cpp
1/*
2 * Copyright (C) 2003,2004 Thiago Macieira <thiago.macieira@kdemail.net>
3 *
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25#include <config.h>
26
27#include <sys/types.h>
28#include <sys/socket.h>
29
30#include "tdesocketaddress.h"
31#include "kresolver.h"
32#include "tdesocketdevice.h"
33#include "kdatagramsocket.h"
34
35using namespace KNetwork;
36
37/*
38 * TODO:
39 *
40 * don't use signals and slots to track state changes: use stateChanging
41 *
42 */
43
44KDatagramSocket::KDatagramSocket(TQObject* parent, const char *name)
45 : KClientSocketBase(parent, name), d(0L)
46{
47 peerResolver().setFamily(KResolver::KnownFamily);
48 localResolver().setFamily(KResolver::KnownFamily);
49
50 peerResolver().setSocketType(SOCK_DGRAM);
51 localResolver().setSocketType(SOCK_DGRAM);
52
53 localResolver().setFlags(KResolver::Passive);
54
55 // TQObject::connect(localResolver(), TQ_SIGNAL(finished(KResolverResults)),
56 // this, TQ_SLOT(lookupFinishedLocal()));
57 TQObject::connect(&peerResolver(), TQ_SIGNAL(finished(KResolverResults)),
58 this, TQ_SLOT(lookupFinishedPeer()));
59 TQObject::connect(this, TQ_SIGNAL(hostFound()), this, TQ_SLOT(lookupFinishedLocal()));
60}
61
62KDatagramSocket::~KDatagramSocket()
63{
64 // KClientSocketBase's destructor closes the socket
65
66 //delete d;
67}
68
69bool KDatagramSocket::bind(const TQString& node, const TQString& service)
70{
71 if (state() >= Bound)
72 return false;
73
74 if (localResolver().isRunning())
75 localResolver().cancel(false);
76
77 // no, we must do a host lookup
78 localResolver().setAddress(node, service);
79
80 if (!lookup())
81 return false;
82
83 // see if lookup has finished already
84 // this also catches blocking mode, since lookup has to finish
85 // its processing if we're in blocking mode
86 if (state() > HostLookup)
87 return doBind();
88
89 return true;
90}
91
92bool KDatagramSocket::connect(const TQString& node, const TQString& service)
93{
94 if (state() >= Connected)
95 return true; // already connected
96
97 if (peerResolver().nodeName() != node ||
98 peerResolver().serviceName() != service)
99 peerResolver().setAddress(node, service); // this resets the resolver's state
100
101 // KClientSocketBase::lookup only works if the state is Idle or HostLookup
102 // therefore, we store the old state, call the lookup routine and then set
103 // it back.
104 SocketState s = state();
105 setState(s == Connecting ? HostLookup : Idle);
106 bool ok = lookup();
107 if (!ok)
108 {
109 setState(s); // go back
110 return false;
111 }
112
113 // check if lookup is finished
114 // if we're in blocking mode, then the lookup has to be finished
115 if (state() == HostLookup)
116 {
117 // it hasn't finished
118 setState(Connecting);
119 emit stateChanged(Connecting);
120 return true;
121 }
122
123 // it has to be finished here
124 if (state() != Connected)
125 {
126 setState(Connecting);
127 emit stateChanged(Connecting);
128 lookupFinishedPeer();
129 }
130
131 return state() == Connected;
132}
133
134KDatagramPacket KDatagramSocket::receive()
135{
136 TQ_LONG size = bytesAvailable();
137 if (size == 0)
138 {
139 // nothing available yet to read
140 // wait for data if we're not blocking
141 if (blocking())
142 socketDevice()->waitForMore(-1); // wait forever
143 else
144 {
145 // mimic error
146 setError(IO_ReadError, WouldBlock);
147 emit gotError(WouldBlock);
148 return KDatagramPacket();
149 }
150
151 // try again
152 size = bytesAvailable();
153 }
154
155 TQByteArray data(size);
156 TDESocketAddress address;
157
158 // now do the reading
159 size = readBlock(data.data(), size, address);
160 if (size < 0)
161 // error has been set
162 return KDatagramPacket();
163
164 data.resize(size); // just to be sure
165 return KDatagramPacket(data, address);
166}
167
168TQ_LONG KDatagramSocket::send(const KDatagramPacket& packet)
169{
170 return writeBlock(packet.data(), packet.size(), packet.address());
171}
172
173TQ_LONG KDatagramSocket::writeBlock(const char *data, TQ_ULONG len, const TDESocketAddress& to)
174{
175 if (to.family() != AF_UNSPEC)
176 {
177 // make sure the socket is open at this point
178 if (!socketDevice()->isOpen())
179 // error handling will happen below
180 socketDevice()->create(to.family(), SOCK_DGRAM, 0);
181 }
182 return KClientSocketBase::writeBlock(data, len, to);
183}
184
185void KDatagramSocket::lookupFinishedLocal()
186{
187 // bind lookup has finished and succeeded
188 // state() == HostFound
189
190 if (!doBind())
191 return; // failed binding
192
193 if (peerResults().count() > 0)
194 {
195 setState(Connecting);
196 emit stateChanged(Connecting);
197
198 lookupFinishedPeer();
199 }
200}
201
202void KDatagramSocket::lookupFinishedPeer()
203{
204 // this function is called by lookupFinishedLocal above
205 // and is also connected to a signal
206 // so it might be called twice.
207
208 if (state() != Connecting)
209 return;
210
211 if (peerResults().count() == 0)
212 {
213 setState(Unconnected);
214 emit stateChanged(Unconnected);
215 return;
216 }
217
218 KResolverResults::ConstIterator it = peerResults().begin();
219 for ( ; it != peerResults().end(); ++it)
220 if (connect(*it))
221 {
222 // weee, we connected
223
224 setState(Connected); // this sets up signals
225 //setupSignals(); // setState sets up the signals
226
227 emit stateChanged(Connected);
228 emit connected(*it);
229 return;
230 }
231
232 // no connection
233 copyError();
234 setState(Unconnected);
235 emit stateChanged(Unconnected);
236 emit gotError(error());
237}
238
239bool KDatagramSocket::doBind()
240{
241 if (localResults().count() == 0)
242 return true;
243 if (state() >= Bound)
244 return true; // already bound
245
246 KResolverResults::ConstIterator it = localResults().begin();
247 for ( ; it != localResults().end(); ++it)
248 if (bind(*it))
249 {
250 // bound
251 setupSignals();
252 return true;
253 }
254
255 // not bound
256 // no need to set state since it can only be HostFound already
257 copyError();
258 emit gotError(error());
259 return false;
260}
261
262void KDatagramSocket::setupSignals()
263{
264 TQSocketNotifier *n = socketDevice()->readNotifier();
265 if (n)
266 {
267 n->setEnabled(emitsReadyRead());
268 TQObject::connect(n, TQ_SIGNAL(activated(int)), this, TQ_SLOT(slotReadActivity()));
269 }
270 else
271 return;
272
273 n = socketDevice()->writeNotifier();
274 if (n)
275 {
276 n->setEnabled(emitsReadyWrite());
277 TQObject::connect(n, TQ_SIGNAL(activated(int)), this, TQ_SLOT(slotWriteActivity()));
278 }
279 else
280 return;
281}
282
283#include "kdatagramsocket.moc"
KNetwork::KActiveSocketBase::size
virtual Offset size() const
This call is not supported on sockets.
Definition tdesocketbase.h:507
KNetwork::KActiveSocketBase::setError
void setError(int status, SocketError error)
Sets the socket's error code and the I/O Device's status.
Definition tdesocketbase.cpp:309
KNetwork::KClientSocketBase
Abstract client socket class.
Definition kclientsocketbase.h:50
KNetwork::KClientSocketBase::connected
void connected(const KResolverEntry &remote)
This socket is emitted when the socket successfully connects to a remote address.
KNetwork::KClientSocketBase::emitsReadyWrite
bool emitsReadyWrite() const
Returns true if the readyWrite signal is set to be emitted.
Definition kclientsocketbase.cpp:398
KNetwork::KClientSocketBase::SocketState
SocketState
Socket states.
Definition kclientsocketbase.h:73
KNetwork::KClientSocketBase::writeBlock
virtual TQ_LONG writeBlock(const char *data, TQ_ULONG len)
Writes data to the socket.
Definition kclientsocketbase.cpp:349
KNetwork::KClientSocketBase::bytesAvailable
virtual TQ_LONG bytesAvailable() const
Returns the number of bytes available on this socket.
Definition kclientsocketbase.cpp:281
KNetwork::KClientSocketBase::slotReadActivity
virtual void slotReadActivity()
This slot is connected to the read notifier's signal meaning the socket can read more data.
Definition kclientsocketbase.cpp:413
KNetwork::KClientSocketBase::localResults
const KResolverResults & localResults() const
Returns the internal list of resolved results for the local address.
Definition kclientsocketbase.cpp:106
KNetwork::KClientSocketBase::setState
void setState(SocketState state)
Sets the socket state to state.
Definition kclientsocketbase.cpp:69
KNetwork::KClientSocketBase::readBlock
virtual TQ_LONG readBlock(char *data, TQ_ULONG maxlen)
Reads data from a socket.
Definition kclientsocketbase.cpp:301
KNetwork::KClientSocketBase::emitsReadyRead
bool emitsReadyRead() const
Returns true if the readyRead signal is set to be emitted.
Definition kclientsocketbase.cpp:383
KNetwork::KClientSocketBase::state
SocketState state() const
Returns the current state for this socket.
Definition kclientsocketbase.cpp:64
KNetwork::KClientSocketBase::gotError
void gotError(int code)
This signal is emitted when this object finds an error.
KNetwork::KClientSocketBase::lookup
virtual bool lookup()
Starts the lookup for peer and local hostnames as well as their services.
Definition kclientsocketbase.cpp:131
KNetwork::KClientSocketBase::peerResolver
KResolver & peerResolver() const
Returns the internal KResolver object used for looking up the peer host name and service.
Definition kclientsocketbase.cpp:91
KNetwork::KClientSocketBase::copyError
void copyError()
Convenience function to set this object's error code to match that of the socket device.
Definition kclientsocketbase.cpp:472
KNetwork::KClientSocketBase::hostFound
void hostFound()
This signal is emitted when the lookup is successfully completed.
KNetwork::KClientSocketBase::slotWriteActivity
virtual void slotWriteActivity()
This slot is connected to the write notifier's signal meaning the socket can write more data.
Definition kclientsocketbase.cpp:419
KNetwork::KClientSocketBase::peerResults
const KResolverResults & peerResults() const
Returns the internal list of resolved results for the peer address.
Definition kclientsocketbase.cpp:96
KNetwork::KClientSocketBase::stateChanged
void stateChanged(int newstate)
This signal is emitted whenever the socket state changes.
KNetwork::KClientSocketBase::localResolver
KResolver & localResolver() const
Returns the internal KResolver object used for looking up the local host name and service.
Definition kclientsocketbase.cpp:101
KNetwork::KDatagramPacket
one datagram
Definition kdatagramsocket.h:52
KNetwork::KDatagramPacket::address
const TDESocketAddress & address() const
Returns the socket address.
Definition kdatagramsocket.h:137
KNetwork::KDatagramPacket::data
const TQByteArray & data() const
Returns the data.
Definition kdatagramsocket.h:107
KNetwork::KDatagramPacket::size
uint size() const
Returns the data length.
Definition kdatagramsocket.h:119
KNetwork::KDatagramSocket::~KDatagramSocket
virtual ~KDatagramSocket()
Destructor.
Definition kdatagramsocket.cpp:62
KNetwork::KDatagramSocket::bind
virtual bool bind(const TQString &node=TQString::null, const TQString &service=TQString::null)
Performs host lookups.
Definition kdatagramsocket.cpp:69
KNetwork::KDatagramSocket::writeBlock
virtual TQ_LONG writeBlock(const char *data, TQ_ULONG len, const TDESocketAddress &to)
Writes data to the socket.
Definition kdatagramsocket.cpp:173
KNetwork::KDatagramSocket::KDatagramSocket
KDatagramSocket(TQObject *parent=0L, const char *name=0L)
Default constructor.
Definition kdatagramsocket.cpp:44
KNetwork::KDatagramSocket::connect
virtual bool connect(const TQString &node=TQString::null, const TQString &service=TQString::null)
"Connects" this socket to the given address.
Definition kdatagramsocket.cpp:92
KNetwork::KDatagramSocket::send
virtual TQ_LONG send(const KDatagramPacket &packet)
Sends one datagram into the stream.
Definition kdatagramsocket.cpp:168
KNetwork::KDatagramSocket::receive
virtual KDatagramPacket receive()
Receives one datagram from the stream.
Definition kdatagramsocket.cpp:134
KNetwork::KResolverResults
Name and service resolution results.
Definition kresolver.h:198
KNetwork::KResolver::cancel
void cancel(bool emitSignal=true)
Cancels a running request.
Definition kresolver.cpp:512
KNetwork::KResolver::setFamily
void setFamily(int families)
Sets the allowed socket families.
Definition kresolver.cpp:401
KNetwork::KResolver::setFlags
int setFlags(int flags)
Sets the flags.
Definition kresolver.cpp:389
KNetwork::KResolver::setSocketType
void setSocketType(int type)
Sets the socket type we want.
Definition kresolver.cpp:411
KNetwork::KResolver::setAddress
void setAddress(const TQString &node, const TQString &service)
Sets both the host and the service names.
Definition kresolver.cpp:376
KNetwork::TDESocketAddress
A generic socket address.
Definition tdesocketaddress.h:424
KNetwork::TDESocketAddress::family
int family() const
Returns the family of this address.
KNetwork::TDESocketBase::error
SocketError error() const
Retrieves the socket error code.
Definition tdesocketbase.cpp:160
KNetwork::TDESocketBase::blocking
bool blocking() const
Retrieves this socket's blocking mode.
Definition tdesocketbase.cpp:81
KNetwork::TDESocketBase::socketDevice
TDESocketDevice * socketDevice() const
Retrieves the socket implementation used on this socket.
Definition tdesocketbase.cpp:116
KNetwork::TDESocketDevice::waitForMore
virtual TQ_LONG waitForMore(int msecs, bool *timeout=0L)
Waits up to msecs for more data to be available on this socket.
Definition tdesocketdevice.cpp:379
KNetwork::TDESocketDevice::create
virtual bool create(int family, int type, int protocol)
Creates a socket but don't connect or bind anywhere.
Definition tdesocketdevice.cpp:201
KNetwork::TDESocketDevice::writeNotifier
TQSocketNotifier * writeNotifier() const
Returns a socket notifier for output on this socket.
Definition tdesocketdevice.cpp:627
KNetwork::TDESocketDevice::readNotifier
TQSocketNotifier * readNotifier() const
Returns a socket notifier for input on this socket.
Definition tdesocketdevice.cpp:609
KNetwork
A namespace to store all networking-related (socket) classes.
Definition kbufferedsocket.h:36

tdecore

Skip menu "tdecore"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

tdecore

Skip menu "tdecore"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdecore by doxygen 1.9.8
This website is maintained by Timothy Pearson.