• 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 
35 using namespace KNetwork;
36 
37 /*
38  * TODO:
39  *
40  * don't use signals and slots to track state changes: use stateChanging
41  *
42  */
43 
44 KDatagramSocket::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 
62 KDatagramSocket::~KDatagramSocket()
63 {
64  // KClientSocketBase's destructor closes the socket
65 
66  //delete d;
67 }
68 
69 bool 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 
92 bool 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 
134 KDatagramPacket 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 
168 TQ_LONG KDatagramSocket::send(const KDatagramPacket& packet)
169 {
170  return writeBlock(packet.data(), packet.size(), packet.address());
171 }
172 
173 TQ_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 
185 void 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 
202 void 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 
239 bool 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 
262 void 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::data
const TQByteArray & data() const
Returns the data.
Definition: kdatagramsocket.h:107
KNetwork::KDatagramPacket::address
const TDESocketAddress & address() const
Returns the socket address.
Definition: kdatagramsocket.h:137
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.
Definition: tdesocketaddress.cpp:499
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
  • Modules
  • 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.1
This website is maintained by Timothy Pearson.