You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1126 lines
38 KiB
1126 lines
38 KiB
/*
|
|
* This file is part of the KDE libraries
|
|
* Copyright (C) 2000-2004 Thiago Macieira <thiago.macieira@kdemail.net>
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Library General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Library General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Library General Public License
|
|
* along with this library; see the file COPYING.LIB. If not, write to
|
|
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
* Boston, MA 02110-1301, USA.
|
|
*/
|
|
#ifndef KEXTSOCK_H
|
|
#define KEXTSOCK_H
|
|
|
|
#include "kdelibs_export.h"
|
|
|
|
#ifdef Q_OS_UNIX
|
|
|
|
#include <sys/time.h>
|
|
|
|
#include <tqstring.h>
|
|
#include <tqptrlist.h>
|
|
#include <tqiodevice.h>
|
|
|
|
#include "kbufferedio.h"
|
|
#include "ksockaddr.h"
|
|
|
|
/* External reference to netdb.h */
|
|
struct addrinfo;
|
|
struct kde_addrinfo;
|
|
class KAddressInfo; /* our abstraction of it */
|
|
class TQSocketNotifier;
|
|
|
|
/*
|
|
* This is extending QIODevice's error codes
|
|
*
|
|
* According to tqiodevice.h, the last error is IO_UnspecifiedError
|
|
* These errors will never occur in functions declared in QIODevice
|
|
* (except open, but you shouldn't call open)
|
|
*/
|
|
#define IO_ListenError (IO_UnspecifiedError+1)
|
|
#define IO_AcceptError (IO_UnspecifiedError+2)
|
|
#define IO_LookupError (IO_UnspecifiedError+3)
|
|
|
|
class KExtendedSocketPrivate;
|
|
/**
|
|
* The extended socket class.
|
|
*
|
|
* This class should be used instead of KSocket whenever the user needs
|
|
* fine-grained control over the socket being created. Unlike KSocket, which
|
|
* does everything at once, without much intervention, KExtendedSocket allows
|
|
* intervention at every step of the process and the setting of parameters.
|
|
*
|
|
* This class allows for the creation of both server and client sockets. The
|
|
* only difference is that the passiveSocket flag must be passed either to
|
|
* the constructor or to setSocketFlags(). If passiveSocket is used, the class will
|
|
* enable functions listen() and accept() and related signals, and will
|
|
* also disable readBlock() and writeBlock().
|
|
*
|
|
* To create a Unix socket, one would pass flag unixSocket to the constructor
|
|
* or setSocketFlags(). The hostname and service/port can be set to whatever is
|
|
* necessary. If no hostname is given, but a service/port is, the socket created
|
|
* will be implementation dependant (usually in /tmp). In any other case, the
|
|
* fields will be concatenated.
|
|
*
|
|
* To create an Internet socket, inetSocket flag can be used. If, on the other
|
|
* hand a specific IP protocol is desired, ipv4Socket and/or ipv6Socket can be
|
|
* used.
|
|
*
|
|
* Note that the socket type selection flags are cumulative. One could select
|
|
* Unix and Internet sockets by using unixSocket | inetSocket. Or, for instance,
|
|
* to make sure only IPv4 and IPv6 sockets are selected, even if future implementations
|
|
* support newer IP protocols, ipv4Socket | ipv6Socket is your guy.
|
|
*
|
|
* @deprecated
|
|
* This class is now deprecated. Please use the classes in KNetwork for
|
|
* new programs. In particular, this class is replaced by KNetwork::KStreamSocket
|
|
* and @ref KNetwork::KServerSocket.
|
|
*
|
|
* @author Thiago Macieira <thiago.macieira@kdemail.net>
|
|
* @short an extended socket
|
|
*/
|
|
class KDECORE_EXPORT KExtendedSocket: public KBufferedIO // public TQObject, public QIODevice
|
|
{
|
|
Q_OBJECT
|
|
|
|
public:
|
|
/**
|
|
* flags that can be passed down to the member functions
|
|
*/
|
|
enum Flags
|
|
{
|
|
/* socket address families */
|
|
/*
|
|
* NOTE: if you change this, you have to change function valid_socket() as well
|
|
* These values are hard coded!
|
|
*/
|
|
anySocket = 0x00,
|
|
knownSocket = 0x01,
|
|
unixSocket = knownSocket | 0x02,
|
|
inetSocket = knownSocket | 0x04,
|
|
ipv4Socket = inetSocket | 0x100,
|
|
ipv6Socket = inetSocket | 0x200,
|
|
|
|
passiveSocket = 0x1000, /* passive socket (i.e., one that accepts connections) */
|
|
canonName = 0x2000, /* request that the canon name be found */
|
|
noResolve = 0x4000, /* do not attempt to resolve, treat as numeric host */
|
|
|
|
streamSocket = 0x8000, /* request a streaming socket (e.g., TCP) */
|
|
datagramSocket = 0x10000, /* request a datagram socket (e.g., UDP) */
|
|
rawSocket = 0x20000, /* request a raw socket. This probably requires privileges */
|
|
|
|
inputBufferedSocket = 0x200000, /* buffer input in this socket */
|
|
outputBufferedSocket = 0x400000, /* buffer output in this socket */
|
|
bufferedSocket = 0x600000 /* make this a fully buffered socket */
|
|
};
|
|
|
|
/**
|
|
* status of the class
|
|
* The status are sequential. If a change to one status is requested,
|
|
* all the prior status will be passed and their actions, performed
|
|
*/
|
|
enum SockStatus
|
|
{
|
|
// the numbers are scattered so that we leave room for future expansion
|
|
error = -1, // invalid status!
|
|
|
|
nothing = 0, // no status, the class has just been created
|
|
|
|
lookupInProgress = 50, // lookup is in progress. Signals will be sent
|
|
lookupDone = 70, // lookup has been done. Flags cannot be changed
|
|
// from this point on
|
|
|
|
created = 100, // ::socket() has been called, a socket exists
|
|
bound = 140, // socket has been bound
|
|
|
|
connecting = 200, // socket is connecting (not passiveSocket)
|
|
connected = 220, // socket has connected (not passiveSocket)
|
|
|
|
listening = 200, // socket is listening (passiveSocket)
|
|
accepting = 220, // socket is accepting (passiveSocket)
|
|
|
|
closing = 350, // socket is closing (delayed close)
|
|
|
|
done = 400 // socket has been closed
|
|
};
|
|
|
|
public:
|
|
/**
|
|
* Creates an empty KExtendedSocket.
|
|
*/
|
|
KExtendedSocket();
|
|
|
|
/**
|
|
* Creates a socket with the given hostname and port.
|
|
*
|
|
* If this is a connecting (active) socket, the hostname and port specify
|
|
* the remote address to which we will connect.
|
|
*
|
|
* If this is a listening (passive) socket, the hostname and port specify
|
|
* the address to listen on. In order to listen on every interface
|
|
* available on this node, set @p host to TQString::null. To let the operating
|
|
* system select a port, set it to 0.
|
|
*
|
|
* @sa setAddress
|
|
* @param host the hostname
|
|
* @param port the port number
|
|
* @param flags flags
|
|
*/
|
|
KExtendedSocket(const TQString& host, int port, int flags = 0);
|
|
|
|
/**
|
|
* Creates a socket with the given hostname and service.
|
|
*
|
|
* If this is a connecting (active) socket, the hostname and service specify
|
|
* the remote address to which we will connect.
|
|
*
|
|
* If this is a listening (passive) socket, the hostname and service specify
|
|
* the address to listen on. In order to listen on every interface
|
|
* available on this node, set @p host to TQString::null. To let the operating
|
|
* system select a port, set the service to "0".
|
|
*
|
|
* @sa setAddress
|
|
* @param host the hostname
|
|
* @param service the service
|
|
* @param flags flags
|
|
*/
|
|
KExtendedSocket(const TQString& host, const TQString& service, int flags = 0);
|
|
|
|
/**
|
|
* Destroys the socket, disconnecting if still connected and
|
|
* freeing any related resources still being kept.
|
|
*/
|
|
virtual ~KExtendedSocket();
|
|
|
|
/**
|
|
* Resets the socket, disconnecting if still connected and
|
|
* freeing any related resources still being kept.
|
|
* @since 3.1
|
|
*/
|
|
#ifdef USE_QT3
|
|
void reset();
|
|
#endif // USE_QT3
|
|
#ifdef USE_QT4
|
|
bool reset();
|
|
#endif // USE_QT4
|
|
|
|
/*
|
|
* --- status, flags and internal variables --- *
|
|
*/
|
|
|
|
/**
|
|
* Returns the class status.
|
|
* @return the class status
|
|
* @see ::SockStatus
|
|
*/
|
|
int socketStatus() const;
|
|
|
|
/**
|
|
* Returns the related system error code
|
|
* Except for IO_LookupError errors, these are codes found in
|
|
* errno
|
|
* @return the system error code
|
|
*/
|
|
int systemError() const;
|
|
|
|
/**
|
|
* Sets the given flags.
|
|
* @param flags the flags to be set
|
|
* @return the new flags status, or -1 if flags can no longer be set
|
|
*/
|
|
int setSocketFlags(int flags);
|
|
|
|
/**
|
|
* Returns the current flags
|
|
* @return the current flags
|
|
* @see ::Flags
|
|
*/
|
|
int socketFlags() const;
|
|
|
|
/**
|
|
* Sets the hostname to the given value.
|
|
*
|
|
* If this is a listening (passive) socket, the hostname is the host to which the socket
|
|
* will bind in order to listen. If you want to listen in every interface, set it
|
|
* to "*" or TQString::null.
|
|
*
|
|
* If this is a connecting (active) socket, the hostname is the host to which we will try
|
|
* to connect.
|
|
*
|
|
* @param host the hostname
|
|
* @return true on success, false on error
|
|
*/
|
|
bool setHost(const TQString& host);
|
|
|
|
/**
|
|
* Returns the hostname.
|
|
* @return the hostname or TQString::null if no host has been set
|
|
*/
|
|
TQString host() const;
|
|
|
|
/**
|
|
* Sets the port/service.
|
|
* @param port the port
|
|
*/
|
|
bool setPort(int port);
|
|
|
|
/**
|
|
* Sets the port/service.
|
|
*
|
|
* In the case of Unix-domain sockets, the port is the filename for the socket.
|
|
* If the name is not an absolute path, "/tmp/" will be prepended.
|
|
*
|
|
* @param port the port
|
|
* @return true if successful, false on error (e.g. connection already established)
|
|
*/
|
|
bool setPort(const TQString& port);
|
|
|
|
/**
|
|
* Returns the port/service. If it is a port, the string contains a number.
|
|
* @return the port or TQString::null if it has not been set.
|
|
*/
|
|
TQString port() const;
|
|
|
|
/**
|
|
* Sets the address where we will connect to.
|
|
*
|
|
* See @ref setHost and @ref setPort for information on the parameters.
|
|
*
|
|
* @param host the hostname
|
|
* @param port port number
|
|
* @return true if successful, false on error (e.g. connection already established)
|
|
*/
|
|
bool setAddress(const TQString& host, int port);
|
|
|
|
/**
|
|
* Sets the address where we will connect to.
|
|
*
|
|
* See @ref setHost and @ref setPort for information on the parameters.
|
|
*
|
|
* @param host the hostname
|
|
* @param serv the service
|
|
* @return true if successful, false on error (e.g. connection already established)
|
|
*/
|
|
bool setAddress(const TQString& host, const TQString& serv);
|
|
|
|
/**
|
|
* Sets the hostname to which we will bind locally before connecting.
|
|
* @param host the hostname
|
|
* @return false if this is a passiveSocket, otherwise true.
|
|
*/
|
|
bool setBindHost(const TQString& host);
|
|
|
|
/**
|
|
* Unsets the bind hostname. That is, don't request a binding host.
|
|
* @return true if successful, false on error (e.g. connection already established)
|
|
*/
|
|
bool unsetBindHost();
|
|
|
|
/**
|
|
* Returns the hostname to which the socket will be/is bound.
|
|
* @return the host or TQString::null if it has not been set.
|
|
*/
|
|
TQString bindHost() const;
|
|
|
|
/**
|
|
* Sets the port/service to which we will bind before connecting
|
|
* @param port the port number
|
|
* @return true if successful, false on error (e.g. connection already established)
|
|
*/
|
|
bool setBindPort(int port);
|
|
|
|
/**
|
|
* Sets the port/service to which we will bind before connecting.
|
|
* @param service the port number or service name
|
|
* @return true if successful, false on error (e.g. connection already established)
|
|
*/
|
|
bool setBindPort(const TQString& service);
|
|
|
|
/**
|
|
* Unsets the bind port/service.
|
|
* @return true if successful, false on error (e.g. connection already established)
|
|
*/
|
|
bool unsetBindPort();
|
|
|
|
/**
|
|
* Returns the service to which the socket will be/is bound.
|
|
* @return the host or TQString::null if it has not been set.
|
|
*/
|
|
TQString bindPort() const;
|
|
|
|
/**
|
|
* Sets both host and port to which we will bind the socket. Will return
|
|
* false if this is a passiveSocket.
|
|
* @param host the hostname
|
|
* @param port the port number
|
|
* @return true if successful, false on error (e.g. connection already established)
|
|
*/
|
|
bool setBindAddress(const TQString& host, int port);
|
|
|
|
/**
|
|
* Sets both host and service to which we will bind the socket. Will return
|
|
* false if this is a passiveSocket.
|
|
* @param host the hostname
|
|
* @param service the service
|
|
* @return true if successful, false on error (e.g. connection already established)
|
|
*/
|
|
bool setBindAddress(const TQString& host, const TQString& service);
|
|
|
|
/**
|
|
* Unsets the bind address for the socket. That means that we won't
|
|
* attempt to bind to an address before connecting.
|
|
* @return true if successful, false on error (e.g. connection already established)
|
|
*/
|
|
bool unsetBindAddress();
|
|
|
|
/**
|
|
* Sets the timeout value for the connection (if this is not passiveSocket) or
|
|
* acception (if it is). In the event the given function
|
|
* (connect or accept) returns due to time out, it's possible to call it again.
|
|
*
|
|
* Setting the timeout to 0 disables the timeout feature.
|
|
*
|
|
* @param secs the timeout length, in seconds
|
|
* @param usecs the timeout complement, in microseconds
|
|
* @return false if setting timeout makes no sense in the context.
|
|
*/
|
|
bool setTimeout(int secs, int usecs = 0);
|
|
|
|
/**
|
|
* Returns the timeout value for the connection.
|
|
* @return the timeout value. 0 if there is no timeout.
|
|
*/
|
|
timeval timeout() const;
|
|
|
|
/**
|
|
* Sets/unsets blocking mode for the socket. When non-blocking mode is enabled,
|
|
* I/O operations might return error and set errno to EWOULDBLOCK. Also,
|
|
* it's not recommended to use this when using the class signals.
|
|
*
|
|
* @param enable if true, set blocking mode. False, non-blocking mode.
|
|
* @return false on error.
|
|
*/
|
|
bool setBlockingMode(bool enable);
|
|
|
|
/**
|
|
* Returns the current blocking mode for this socket.
|
|
* @return true if in blocking mode
|
|
*/
|
|
bool blockingMode();
|
|
|
|
/**
|
|
* Sets/unsets address reusing flag for this socket.
|
|
*
|
|
* This function returns true if the value was set correctly. That is NOT
|
|
* the result of the set.
|
|
* @param enable if true, set address reusable
|
|
* @return true on success, false on failure. If the socket was not yet created,
|
|
* the value is only remembered. In this case the return value is always true.
|
|
*/
|
|
bool setAddressReusable(bool enable);
|
|
|
|
/**
|
|
* Returns whether this socket's address can be reused
|
|
* @return true if the address can be reused
|
|
*/
|
|
bool addressReusable();
|
|
|
|
/**
|
|
* Sets/unsets the v6-only flag for IPv6 sockets.
|
|
*
|
|
* When an IPv6 socket is in use, communication with IPv4 sockets is
|
|
* guaranteed by translating those IPv4 addresses into IPv6 ones
|
|
* (specifically, the v4-mapped addresses). This flag allows that
|
|
* behavior to be turned on and off.
|
|
*
|
|
* Note that this does not have any effect on sockets that are not
|
|
* IPv6 and the function will always return false in those cases.
|
|
* Also note that this flag defaults to off in order to accommodate
|
|
* existing applications.
|
|
*
|
|
* @param enable if true, no IPv4 translation will be performed;
|
|
* this socket will be restricted to IPv6 communication
|
|
* @returns true on success, false on failure.
|
|
* @see localAddress to find out if this is an IPv6 socket
|
|
*/
|
|
bool setIPv6Only(bool enable);
|
|
|
|
/**
|
|
* Returns the status of the v6-only flag for IPv6 sockets.
|
|
* @returns true if the flag is set to on; false if it is not. If this
|
|
* socket is not an IPv6 one, the return value is false.
|
|
* @see setIPv6Only
|
|
*/
|
|
bool isIPv6Only();
|
|
|
|
/**
|
|
* Sets the buffer sizes for this socket.
|
|
*
|
|
* This implementation allows any size for both parameters. The value given
|
|
* will be interpreted as the maximum size allowed for the buffers, after
|
|
* which the I/O functions will stop buffering. The value of -1 will be
|
|
* interpreted as "unlimited" size. The value of -2 means "no change".
|
|
*
|
|
* Note: changing the buffer size to 0 for any buffer will cause the given
|
|
* buffer's to be discarded. Likewise, setting the size to a value less than
|
|
* the current size will cause the buffer to be shrunk to the wanted value,
|
|
* as if the data had been read.
|
|
* @param rsize read buffer size
|
|
* @param wsize write buffer size
|
|
* @return true on success, false if this is not possible in this state (e.g. connection
|
|
* not established yet)
|
|
*/
|
|
virtual bool setBufferSize(int rsize, int wsize = -2);
|
|
|
|
/**
|
|
* Returns the local socket address
|
|
* @return the local socket address, can be 0 if the connection has not been established
|
|
* yet
|
|
*/
|
|
const ::KSocketAddress *localAddress();
|
|
|
|
/**
|
|
* Returns the peer socket address. Use KExtendedSocket::resolve() to
|
|
* resolve this to a human-readable hostname/service or port.
|
|
* @return the peer address, can be 0 if the connection has not been established yet
|
|
* or the socket is passive
|
|
*/
|
|
const ::KSocketAddress *peerAddress();
|
|
|
|
/**
|
|
* Returns the file descriptor
|
|
* @return the file descriptor. -1 if there is no fd yet.
|
|
*/
|
|
inline int fd() const
|
|
{ return sockfd; }
|
|
|
|
/*
|
|
* -- socket creation -- *
|
|
*/
|
|
|
|
/**
|
|
* Performs lookup on the addresses we were given before.
|
|
*
|
|
* This will perform lookups on the bind addresses if they were given.
|
|
* @return 0 or an error. Do not rely on the values returned by lookup
|
|
* as of now. They are not specified.
|
|
*/
|
|
virtual int lookup();
|
|
|
|
/**
|
|
* Starts an asynchronous lookup for the addresses given.
|
|
*
|
|
* When the lookup is done, the lookupReady signal will be emitted.
|
|
*
|
|
* Note that, depending on the parameters for the lookup, this function might
|
|
* know the results without the need for blocking or queuing an
|
|
* asynchronous lookup. That means that the lookupReady signal might be
|
|
* emitted by this function, so your code should be prepared for that.
|
|
*
|
|
* One such case is when noResolve flag is set.
|
|
* If this function is able to determine the results without queuing
|
|
* and the lookup failed, this function will return -1.
|
|
*
|
|
* @return 0 on success or -1 on error. Note that
|
|
* returning 0 means that either we are in the process of doing
|
|
* lookup or that it has finished already.
|
|
*/
|
|
virtual int startAsyncLookup();
|
|
|
|
/**
|
|
* Cancels any on-going asynchronous lookups
|
|
*/
|
|
virtual void cancelAsyncLookup();
|
|
|
|
/**
|
|
* Place the socket in listen mode. The parameters are the same as for
|
|
* the system listen() call.
|
|
* @param N the queue length for pending connections
|
|
* @return 0 on success, -1 on system error (errno
|
|
* available) and -2 if this is not a passiveSocket.
|
|
*/
|
|
virtual int listen(int N = 5); // 5 is arbitrary
|
|
|
|
/**
|
|
* Accepts an incoming connection from the socket. If this socket is in
|
|
* blocking mode, this function will block until a connection is received.
|
|
* Otherwise, it might return with error. The sock parameter will be
|
|
* initialised with the newly created socket.
|
|
*
|
|
* Upon successful acception (i.e., this function returns 0), the newly
|
|
* created socket will be already connected. The socket will be unbuffered
|
|
* and readyRead() and readyWrite() signals will be disabled.
|
|
*
|
|
* @param sock a pointer to an KExtendedSocket variable
|
|
* @return 0 on success, -1 on system error (errno set) and -2 if this is
|
|
* not a passiveSocket and -3 if this took too long (time out)
|
|
*/
|
|
virtual int accept(KExtendedSocket *&sock);
|
|
|
|
/**
|
|
* Attempts to connect to the remote host.
|
|
* After successful connection (return value 0), the socket will be ready
|
|
* for I/O operations. Note, however, that not all signals may be enabled
|
|
* for emission by this socket:
|
|
* @li readyRead and readyWrite signals will be enabled only if
|
|
* enableRead or enableWrite were called. You can still enable
|
|
* them by calling those functions, of course.
|
|
* @li #closed() will only be sent if we are indeed reading from the input
|
|
* stream. That is, if this socket is buffering the input. See setBufferSize
|
|
*
|
|
* Note that, in general, functions inherited/overridden from KBufferedIO will only
|
|
* work on buffered sockets, like bytesAvailable and bytesToWrite.
|
|
* @return The return values are:
|
|
* @li 0: success
|
|
* @li -1: system error, errno was set accordingly
|
|
* @li -2: this socket cannot connect(); this is a passiveSocket. It can also
|
|
* mean that the function was unable to make a connection with the given
|
|
* bind address or that an asynchronous connection attempt is already
|
|
* in progress.
|
|
* @li -3: connection timed out
|
|
*
|
|
*/
|
|
virtual int connect();
|
|
|
|
/**
|
|
* Starts an asynchronous connect. This works exactly the same as #connect,
|
|
* except that the connection result won't be returned.
|
|
*
|
|
* Note that those signals might be emitted before this function returns, so your
|
|
* code should be prepared for that condition.
|
|
*
|
|
* You must call cancelAsyncConnect() before you delete the socket if you
|
|
* call this. Otherwise you will have crashes.
|
|
*
|
|
* @return 0 on successful queuing of the connect or -1 on error.
|
|
* If this function returns 0, then the connectionSuccess() or the
|
|
* connectionFailed() signals will be emitted.
|
|
*/
|
|
virtual int startAsyncConnect();
|
|
|
|
/**
|
|
* Cancels any on-going asynchronous connection attempt.
|
|
*/
|
|
virtual void cancelAsyncConnect();
|
|
|
|
/**
|
|
* Implementation of TQIODevice::open() pure virtual function.
|
|
* This depends on the target host address already being there.
|
|
* If this is a passiveSocket, this is identical to call listen(); else, if
|
|
* this is not a passiveSocket and no connection attempt is in progress, this
|
|
* is like connect(). If one is in progress, this function will fail.
|
|
* @param mode the open mode. Must be IO_Raw | IO_ReadWrite
|
|
* @return true if successful, false when an error occurred or the most was
|
|
* not correct
|
|
*/
|
|
virtual bool open(int mode = IO_Raw | IO_ReadWrite);
|
|
|
|
/**
|
|
* Closes the socket. If we have data still in the write buffer yet to be
|
|
* sent, the socket won't be closed right now. It'll be closed after we managed
|
|
* to send everything out.
|
|
* If you want to close the socket now, you may want to call flush() first,
|
|
* and then closeNow().
|
|
*/
|
|
virtual void close();
|
|
|
|
/**
|
|
* Closes the socket now, discarding the contents of the write buffer, if any.
|
|
* The read buffer's contents are kept until they are emptied by read operations
|
|
* or the class is destroyed.
|
|
*/
|
|
virtual void closeNow();
|
|
|
|
/**
|
|
* Releases the socket and anything we have holding on it. The class cannot
|
|
* be used anymore. In other words, this is just like closeNow(), but it does
|
|
* not actually close the socket.
|
|
*
|
|
* This is useful if you just want to connect and don't need the rest of the
|
|
* class.
|
|
*
|
|
* Note that the buffers' contents will be discarded.
|
|
*
|
|
* Use of this method is discouraged, because the socket created might be such that
|
|
* normal library routines can't handle (read, write, close, etc.)
|
|
*/
|
|
virtual void release();
|
|
|
|
/*
|
|
* -- I/O --
|
|
*/
|
|
|
|
/**
|
|
* Flushes the socket buffer. You need not call this method during normal
|
|
* operation as we will try and send everything as soon as possible.
|
|
* However, if you want to make sure that data in the buffer is being sent
|
|
* at this moment, you can call this function. It will try to send as much
|
|
* data as possible, but it will stop as soon as the kernel cannot receive
|
|
* any more data, and would possibly block.
|
|
*
|
|
* By repeatedly calling this function, the behavior will be like that of
|
|
* a blocking socket. Indeed, if this function is called with the kernel not
|
|
* ready to receive data, it will block, unless this is a non-blocking socket.
|
|
*
|
|
* This function does not touch the read buffer. You can empty it by calling
|
|
* readBlock() with a null destination buffer.
|
|
*/
|
|
virtual void flush();
|
|
|
|
/**
|
|
* Returns length of this socket. This call is not supported on sockets.
|
|
* @return the length of this socket, or 0 if unsupported
|
|
*/
|
|
#ifdef USE_QT3
|
|
virtual inline Q_ULONG size() const
|
|
#endif // USE_QT3
|
|
#ifdef USE_QT4
|
|
virtual inline qint64 size() const
|
|
#endif // USE_QT4
|
|
{ return 0; }
|
|
|
|
/**
|
|
* Returns relative position from start. This call is not supported on sockets.
|
|
* @return the relative position from the start, or 0 if unsupported
|
|
*/
|
|
virtual inline Q_ULONG at() const
|
|
{ return 0; }
|
|
|
|
/**
|
|
* Returns true if we are at position. This is not supported on sockets.
|
|
* @param i the position to check
|
|
* @return true if we art at the given position, or always true if unsupported.
|
|
*/
|
|
virtual inline bool at(int i)
|
|
{ Q_UNUSED(i);return true; }
|
|
|
|
/**
|
|
* Returns true if we are at the end. This is not supported on sockets, but
|
|
* we always are at the end in a socket...
|
|
* @return true if we are at the end. Always false if unsupported.
|
|
*/
|
|
virtual inline bool atEnd() const
|
|
{ return false; }
|
|
|
|
/**
|
|
* Reads a block of data from the socket.
|
|
*
|
|
* If the socket is not buffered, this function will simply call the underlying
|
|
* read method. This function will block if the socket is not on non-blocking mode
|
|
* (see setBlockingMode) and there is not enough data to be read in the
|
|
* Operating System yet. If we are in non-blocking operation, the call will
|
|
* fail in this case.
|
|
*
|
|
* However, if we are buffering, this function will instead read from the
|
|
* buffer while there is available data. This function will never block
|
|
* in buffering mode, which means that if you try to read while the buffers
|
|
* are empty, this function will always return -1 and set the system error to
|
|
* EWOULDBLOCK (aka EAGAIN), so as to mimic non-blocking operation.
|
|
*
|
|
* @param data where we will write the read data to
|
|
* @param maxlen maximum length of data to be read
|
|
* @return the number of bytes effectively read, or a negative number in case
|
|
* or an error. If the @p data param is not null, then this is also the number
|
|
* of bytes copied into that buffer. If the return value is different than
|
|
* @p maxlen, then this function encountered a situation in which no more
|
|
* bytes were available. Subsequent calls might cause this function to one
|
|
* of these behaviours:
|
|
* @li return an error, with EWOULDBLOCK system error, if we buffering
|
|
* or we are in non-blocking mode
|
|
* @li otherwise, it'll block
|
|
* This function returns 0, if the function detected end-of-file condition
|
|
* (socket was closed)
|
|
*/
|
|
virtual Q_LONG readBlock(char *data, Q_ULONG maxlen);
|
|
|
|
/**
|
|
* Writes a block of data to the socket.
|
|
*
|
|
* If the socket is not buffered, this function will simply call the underlying
|
|
* write method. This means that the function might block if that method blocks
|
|
* as well. That situation is possible if we are not in non-blocking mode and
|
|
* the operating system buffers are full for this socket. If we are in
|
|
* non-blocking mode and the operating system buffers are full, this function
|
|
* will return -1 and the system error will be set to EWOULDBLOCK.
|
|
*
|
|
* If we are buffering, this function will simply transfer the data into the
|
|
* write buffer. This function will then always succeed, as long as there is
|
|
* enough room in the buffer. If the buffer size was limited and that limit
|
|
* is reached, this function will copy no more bytes than that limit. Trying
|
|
* to write with a full buffer will return -1 and set system error to
|
|
* EWOULDBLOCK.
|
|
*
|
|
* @param data the data to write
|
|
* @param len the length of data to write
|
|
* @return the number of bytes written from @p data buffer.
|
|
* The return value might be less than @p len if the output buffers cannot
|
|
* accommodate that many bytes and -1 in the case of an errro.
|
|
*/
|
|
virtual Q_LONG writeBlock(const char *data, Q_ULONG len);
|
|
|
|
/**
|
|
* Peeks at a block of data from the socket.
|
|
*
|
|
* This is exactly like read, except that the data won't be flushed from the
|
|
* read buffer.
|
|
*
|
|
* If this socket is not buffered, this function will always return with
|
|
* 0 bytes copied.
|
|
*
|
|
* @param data where to store the data
|
|
* @param maxlen how many bytes to copy, at most
|
|
* @return the number of bytes copied. 0 does not mean end-of-file
|
|
* condition.
|
|
*/
|
|
virtual int peekBlock(char *data, uint maxlen);
|
|
|
|
/**
|
|
* Reimplementation of unreadBlock() method. This is so because unreading in
|
|
* sockets doesn't make sense, so this function will always return -1 (error)
|
|
* and set the system error to ENOSYS.
|
|
* @return always -1 (error)
|
|
*/
|
|
virtual int unreadBlock(const char *data, uint len);
|
|
|
|
/**
|
|
* Returns the number of available bytes yet to be read via readBlock
|
|
* and family of functions.
|
|
*
|
|
* Note: as of now, this only works on input-buffered sockets. This will
|
|
* change in the future
|
|
* @return The number of available bytes, or -1 on error or -2 if this call is invalid
|
|
* in the current state.
|
|
*/
|
|
#ifdef USE_QT3
|
|
virtual int bytesAvailable() const;
|
|
#endif // USE_QT3
|
|
#ifdef USE_QT4
|
|
virtual qint64 bytesAvailable() const;
|
|
#endif // USE_QT4
|
|
|
|
/**
|
|
* Waits @p msec milliseconds for more data to be available (use 0 to
|
|
* wait forever). The return value is the amount of data available for
|
|
* read in the read buffer.
|
|
*
|
|
* @param msec milliseconds to wait
|
|
* @return -1 in case of system error and -2 in case of invalid socket
|
|
* state
|
|
*/
|
|
virtual int waitForMore(int msec);
|
|
|
|
/**
|
|
* Gets a single character (unsigned char) from the stream.
|
|
* @return the value of the character. Negative if there was an error.
|
|
*/
|
|
virtual int getch();
|
|
|
|
/**
|
|
* Writes a single character (unsigned char) to the stream. All other bits
|
|
* will be ignored.
|
|
* @param ch character to write, converted to char
|
|
*/
|
|
virtual int putch(int ch);
|
|
|
|
/**
|
|
* Unreads one character from the stream. This is not possible on sockets.
|
|
* @return always returns -1 on sockets.
|
|
*/
|
|
virtual int ungetch(int)
|
|
{ return -1; }
|
|
|
|
/**
|
|
* Toggles the emission of the readyRead signal.
|
|
*
|
|
* Note that this signal is emitted every time more data is available to be
|
|
* read, so you might get flooded with it being emitted every time, when in
|
|
* non-buffered mode. However, in buffered mode, this signal will be
|
|
* emitted only when there is data coming in from the wire.
|
|
* By default, this flag is set to false, i.e., signal not being emitted.
|
|
* @param enable if true, the signal will be emitted
|
|
*/
|
|
virtual void enableRead(bool enable);
|
|
|
|
/**
|
|
* Toggles the emission of the readyWrite signal.
|
|
*
|
|
* Note that this signal is emitted only when the OS is ready to receive more
|
|
* data, which means that the write buffer is empty. And when that is reached,
|
|
* this signal will possibly be emitted on every loop, so you might
|
|
* want to disable it. By default, this flag is set to false.
|
|
* @param enable if true, the signal will be emitted
|
|
*/
|
|
virtual void enableWrite(bool enable);
|
|
|
|
signals:
|
|
/**
|
|
* This signal is emitted whenever an asynchronous lookup process is done.
|
|
* The parameter @p count tells
|
|
* @param count the number of results
|
|
*/
|
|
void lookupFinished(int count);
|
|
|
|
/**
|
|
* This signal is emitted whenever we connected asynchronously to a host.
|
|
*/
|
|
void connectionSuccess();
|
|
|
|
/**
|
|
* This signal is emitted whenever our asynchronous connection attempt
|
|
* failed to all hosts listed.
|
|
* @param error the errno code of the last connection attempt
|
|
*/
|
|
void connectionFailed(int error);
|
|
|
|
/**
|
|
* This signal is emitted whenever this socket is ready to accept another
|
|
* socket.
|
|
* @see accept()
|
|
*/
|
|
void readyAccept();
|
|
|
|
protected:
|
|
int sockfd; // file descriptor of the socket
|
|
|
|
protected slots:
|
|
|
|
void socketActivityRead();
|
|
void socketActivityWrite();
|
|
void dnsResultsReady();
|
|
void startAsyncConnectSlot();
|
|
void connectionEvent();
|
|
|
|
protected:
|
|
|
|
TQSocketNotifier *readNotifier();
|
|
TQSocketNotifier *writeNotifier();
|
|
|
|
private:
|
|
|
|
// protection against accidental use
|
|
KExtendedSocket(KExtendedSocket&);
|
|
KExtendedSocket& operator=(KExtendedSocket&);
|
|
|
|
/**
|
|
* This is actually a wrapper around getaddrinfo().
|
|
* @internal
|
|
*/
|
|
static int doLookup(const TQString& host, const TQString& serv, addrinfo& hint,
|
|
kde_addrinfo** result);
|
|
|
|
protected:
|
|
/**
|
|
* Sets the error code
|
|
*/
|
|
void setError(int errorkind, int error);
|
|
|
|
inline void cleanError()
|
|
{ setError(IO_Ok, 0); }
|
|
|
|
/**
|
|
* Sets the socket status. For derived classes only.
|
|
*/
|
|
void setSocketStatus(int status);
|
|
|
|
public:
|
|
/**
|
|
* Performs resolution on the given socket address.
|
|
*
|
|
* That is, tries to resolve the raw form of the socket address into a textual
|
|
* representation.
|
|
*
|
|
* @param sock the socket address
|
|
* @param len the length of the socket address
|
|
* @param host where the hostname will be written
|
|
* @param port where the service-port will be written
|
|
* @param flags the same flags as getnameinfo()
|
|
* @returns 0 on success, nonzero otherwise.
|
|
*/
|
|
static int resolve(sockaddr* sock, ksocklen_t len, TQString& host, TQString& port, int flags = 0) KDE_DEPRECATED;
|
|
|
|
/**
|
|
* Performs resolution on the given socket address.
|
|
*
|
|
* That is, tries to resolve the raw form of the socket address into a textual
|
|
* representation.
|
|
*
|
|
* @param sock the socket address
|
|
* @param host where the hostname will be written
|
|
* @param port where the service-port will be written
|
|
* @param flags the same flags as getnameinfo()
|
|
* @returns 0 on success, nonzero otherwise.
|
|
*/
|
|
static int resolve(::KSocketAddress* sock, TQString& host, TQString& port, int flags = 0) KDE_DEPRECATED;
|
|
|
|
/** @deprecated
|
|
* This function is now deprecated. Please use @ref KNetwork::KResolver::resolve.
|
|
*
|
|
* Performs lookup on the given hostname/port combination and returns a list
|
|
* of matching addresses.
|
|
* The error code can be transformed into string by KExtendedSocket::strError()
|
|
* with code of IO_LookupError.
|
|
*
|
|
* IMPORTANT: the result values of the TQPtrList must be deleted after use. So,
|
|
* if you don't copy the KAddressInfo objects, the best way to assure that
|
|
* is to call setAutoDelete(true) on the list right after this function
|
|
* returns. If you do copy the results out, you must assure that the objects
|
|
* get deleted when they are not needed any more.
|
|
*
|
|
* @param host the hostname to look up
|
|
* @param port the port/service to look up
|
|
* @param flags flags to be used when looking up, Flags
|
|
* @param error pointer to a variable holding the error code
|
|
* @return a list of KAddressInfos
|
|
*/
|
|
static TQPtrList<KAddressInfo> lookup(const TQString& host, const TQString& port, int flags = 0, int *error = 0) KDE_DEPRECATED;
|
|
|
|
/**
|
|
* Returns the local socket address
|
|
* Remember to delete the returned object when it is no longer needed.
|
|
* @param fd the file descriptor
|
|
* @return the local socket address or 0 if an error occurred. Delete after use.
|
|
*/
|
|
static ::KSocketAddress *localAddress(int fd) KDE_DEPRECATED;
|
|
|
|
/**
|
|
* Returns the peer socket address. Use KExtendedSocket::resolve() to
|
|
* resolve this to a human-readable hostname/service or port.
|
|
* Remember to delete the returned object when it is no longer needed.
|
|
* @param fd the file descriptor
|
|
* @return the peer socket address or 0 if an error occurred. Delete after use.
|
|
*/
|
|
static ::KSocketAddress *peerAddress(int fd) KDE_DEPRECATED;
|
|
|
|
/**
|
|
* Returns the representing text of this error code
|
|
* @param code the error code, as seen in status()
|
|
* @param syserr the system error, as from systemError()
|
|
* @return the text for the given error code
|
|
*/
|
|
static TQString strError(int code, int syserr);
|
|
|
|
/**
|
|
* Sets/unsets address reusing flag for this socket.
|
|
*
|
|
* This function returns true if the value was set correctly. That is NOT
|
|
* the result of the set.
|
|
* @param fd the file descriptor
|
|
* @param enable if true, set address reusable
|
|
* @return true on success, false on failure.
|
|
*/
|
|
static bool setAddressReusable(int fd, bool enable) KDE_DEPRECATED;
|
|
|
|
protected:
|
|
virtual void virtual_hook( int id, void* data );
|
|
private:
|
|
KExtendedSocketPrivate *d;
|
|
|
|
friend class KSocket;
|
|
friend class KServerSocket;
|
|
};
|
|
|
|
/** @deprecated
|
|
* This class is now deprecated. Please see @ref KNetwork::KResolver for the new API.
|
|
*
|
|
* Contains information about an internet address. It wraps addrinfo,
|
|
* see getaddrinfo(3) for more information.
|
|
*/
|
|
class KDECORE_EXPORT KAddressInfo
|
|
{
|
|
private:
|
|
addrinfo *ai;
|
|
::KSocketAddress *addr;
|
|
|
|
inline KAddressInfo() : ai(0), addr(0)
|
|
{ }
|
|
|
|
// KAddressInfo(addrinfo *ai);
|
|
KAddressInfo(KAddressInfo&) { }
|
|
KAddressInfo& operator=(KAddressInfo&) { return *this; }
|
|
|
|
public:
|
|
~KAddressInfo();
|
|
|
|
/**
|
|
* Returns the KAddressInfo's KSocketAddress.
|
|
* Only valid as long as the KAddressInfo exists.
|
|
*/
|
|
inline KDE_DEPRECATED operator const ::KSocketAddress*() const
|
|
{ return addr; }
|
|
|
|
/**
|
|
* Returns the KAddressInfo's addrinfo.
|
|
*/
|
|
inline KDE_DEPRECATED operator const addrinfo&() const
|
|
{ return *ai; }
|
|
|
|
/**
|
|
* Returns a pointer to KAddressInfo's addrinfo.
|
|
* Only valid as long as the KAddressInfo exists.
|
|
*/
|
|
inline KDE_DEPRECATED operator const addrinfo*() const
|
|
{ return ai; }
|
|
|
|
/**
|
|
* Returns the KAddressInfo's KSocketAddress.
|
|
* Only valid as long as the KAddressInfo exists.
|
|
* @return the KAddressInfo's KSocketAddress.
|
|
*/
|
|
inline KDE_DEPRECATED const ::KSocketAddress* address() const
|
|
{ return addr; }
|
|
|
|
/**
|
|
* Returns the flags of the address info (see getaddrinfo(3)).
|
|
* @return the flags of the addres info.
|
|
*/
|
|
int flags() const KDE_DEPRECATED;
|
|
|
|
/**
|
|
* Returns the family of the address info (see getaddrinfo(3)).
|
|
* @return the family of the addres info.
|
|
*/
|
|
int family() const KDE_DEPRECATED;
|
|
|
|
/**
|
|
* Returns the socket type of the address info (see getaddrinfo(3)).
|
|
* @return the socket type of the addres info.
|
|
*/
|
|
int socktype() const KDE_DEPRECATED;
|
|
|
|
/**
|
|
* Returns the protocol of the address info (see getaddrinfo(3)).
|
|
* @return the protocol of the addres info.
|
|
*/
|
|
int protocol() const KDE_DEPRECATED;
|
|
|
|
|
|
/**
|
|
* Returns the official name of the host (see getaddrinfo(3)).
|
|
* Only valid as long as the KAddressInfo exists.
|
|
* @return the official name of the host
|
|
*/
|
|
const char* canonname() const KDE_DEPRECATED;
|
|
|
|
/**
|
|
* Returns the length of the KSocketAddress.
|
|
* @return the KSocketAddress's length
|
|
*/
|
|
inline int length() const
|
|
{ if (addr) return addr->size(); return 0; }
|
|
|
|
friend class KExtendedSocket;
|
|
};
|
|
|
|
#endif //Q_OS_UNIX
|
|
|
|
#endif // KEXTSOCK_H
|