Source Code (Use browser search to find items of interest.)
Class Index
kdelibs'KSocket (./kdelibs/kdecore/ksock.h:72)
class KSocket : public QObject
{
Q_OBJECT
public:
/**
* Create a KSocket with the provided file descriptor.
* @param _sock The file descriptor to use.
*/
KSocket( int _sock );
/**
* Create a socket and connect to a host.
* @param _host The remote host to which to connect.
* @param _port The port on the remote host.
* @param timeOut The number of seconds waiting for connect (default 30).
*/
KSocket( const char *_host, unsigned short int _port, int timeOut = 30);
/**
* Connects to a UNIX domain socket.
* @param _path The filename of the socket.
*/
KSocket( const char * _path );
/**
* Destructor. Closes the socket if it is still open.
*/
~KSocket();
/**
* A small wrapper around @ref gethostbyname() and such.
*/
static bool initSockaddr(ksockaddr_in *server_name, const char *hostname, unsigned short int port, int domain = PF_INET);
/**
* Returns a file descriptor for this socket.
*/
int socket() const { return sock; }
/**
* Enable the socket for reading.
*
* If you enable read mode, the socket will emit the signal
* @ref readEvent() whenever there is something to read out of this
* socket.
*/
void enableRead( bool );
/**
* Enable the socket for writing.
*
* If you enable write mode, the socket will emit the signal
* @ref writeEvent() whenever the socket is ready for writing.
*/
void enableWrite( bool );
/**
* Return address.
*/
unsigned long ipv4_addr();
signals:
/**
* Data has arrived for reading.
*
* This signal will only be raised if @ref enableRead( @p true ) was called
* first.
*/
void readEvent( KSocket * );
/**
* Socket is ready for writing.
*
* This signal will only be raised if @ref enableWrite( @p true ) was
* called first.
*/
void writeEvent( KSocket * );
/**
* Raised when the connection is broken.
*/
void closeEvent( KSocket * );
public slots:
/**
* Connected to the writeNotifier.
*
* Called when
* the socket is ready for writing.
*/
void slotWrite( int );
/**
* Connected to the readNotifier.
*
* Called when
* the socket is ready for reading.
*/
void slotRead( int );
protected:
bool connect( const QString& _host, unsigned short int _port );
bool connect( const char *_path );
bool init_sockaddr( const QString& hostname, unsigned short int port );
ksockaddr_in server_name;
struct sockaddr_un unix_addr;
/******************************************************
* The file descriptor for this socket. sock may be -1.
* This indicates that it is not connected.
*/
int sock;
int domain;
QSocketNotifier *readNotifier;
QSocketNotifier *writeNotifier;
private:
int timeOut;
KSocket(const KSocket&);
KSocket& operator=(const KSocket&);
KSocketPrivate *d;
};
/**
* Monitor a port for incoming TCP/IP connections.
*
* You can use a KServerSocket to listen on a port for incoming
* connections. When a connection arrived in the port, a KSocket
* is created and the signal accepted is raised. Make sure you
* always connect to this signal. If you dont the ServerSocket will
* create new KSocket's and no one will delete them!
*
* If socket() is -1 or less the socket was not created properly.
*
* @author Torben Weis <weis@stud.uni-frankfurt.de>
* @version $Id: ksock.h,v 1.38 2000/03/08 19:46:49 granroth Exp $
* @short Monitor a port for incoming TCP/IP connections.
*/
kdelibs'KSocket::KSocket() (./kdelibs/kdecore/ksock.cpp:76)
KSocket::KSocket( int _sock)
: sock(_sock), readNotifier(0), writeNotifier(0)
{
struct sockaddr_in sin;
ksize_t len = sizeof(sin);
memset(&sin, 0, len);
// getsockname will fill in all the appropiate details, and
// since sockaddr_in will exist everywhere and is somewhat compatible
// with sockaddr_in6, we can use it to avoid needless ifdefs.
getsockname(_sock, (struct sockaddr *)&sin, &len);
// Now that we've got the domain, remember it
domain = sin.sin_family;
}
kdelibs'KSocket::KSocket() (./kdelibs/kdecore/ksock.cpp:93)
KSocket::KSocket( const char *_host, unsigned short int _port, int _timeout ) :
sock( -1 ), readNotifier( 0L ), writeNotifier( 0L )
{
timeOut = _timeout;
#ifdef INET6
// Setup the resolver to look for IPv6 addresses and then
// as a fall back, look for IPv4. This means we don't need further
// ifdefs to use gethostbyname2. (Taken from rfc2133)
res_init();
_res.options |= RES_USE_INET6;
// Also we do this because gethostbyname will return IPv4 mapped on to
// IPv6 addresses when set like this and use 16 byte hostents, so we
// should be safe and use sockaddr_in6, etc, and by setting the domain to
// PF_INET6, anyone who checks our sockaddr stuff will avoid buffer
// overflows by seeing that it's new style.
domain = PF_INET6;
#else
domain = PF_INET;
#endif
connect( _host, _port );
}
kdelibs'KSocket::KSocket() (./kdelibs/kdecore/ksock.cpp:116)
KSocket::KSocket( const char *_path ) :
sock( -1 ), readNotifier( 0L ), writeNotifier( 0L )
{
timeOut = 0; // Not used
domain = PF_UNIX;
connect( _path );
}
kdelibs'KSocket::enableRead() (./kdelibs/kdecore/ksock.cpp:124)
void KSocket::enableRead( bool _state )
{
if ( _state )
{
if ( !readNotifier )
{
readNotifier = new QSocketNotifier( sock, QSocketNotifier::Read );
QObject::connect( readNotifier, SIGNAL( activated(int) ), this, SLOT( slotRead(int) ) );
}
else
readNotifier->setEnabled( true );
}
else if ( readNotifier )
readNotifier->setEnabled( false );
}
kdelibs'KSocket::enableWrite() (./kdelibs/kdecore/ksock.cpp:140)
void KSocket::enableWrite( bool _state )
{
if ( _state )
{
if ( !writeNotifier )
{
writeNotifier = new QSocketNotifier( sock, QSocketNotifier::Write );
QObject::connect( writeNotifier, SIGNAL( activated(int) ), this,
SLOT( slotWrite(int) ) );
}
else
writeNotifier->setEnabled( true );
}
else if ( writeNotifier )
writeNotifier->setEnabled( false );
}
kdelibs'KSocket::slotRead() (./kdelibs/kdecore/ksock.cpp:157)
void KSocket::slotRead( int )
{
char buffer[2];
int n = recv( sock, buffer, 1, MSG_PEEK );
if ( n <= 0 )
emit closeEvent( this );
else
emit readEvent( this );
}
kdelibs'KSocket::slotWrite() (./kdelibs/kdecore/ksock.cpp:168)
void KSocket::slotWrite( int )
{
emit writeEvent( this );
}
/*
* Initializes a sockaddr structure. Do this after creating a socket and
* before connecting to any other socket. Here you must specify the
* host and port you want to connect to.
*/
kdelibs'KSocket::init_sockaddr() (./kdelibs/kdecore/ksock.cpp:178)
bool KSocket::init_sockaddr( const QString& hostname, unsigned short int port )
{
if (
#ifdef INET6
( domain != PF_INET6 ) &&
#endif
( domain != PF_INET ) )
return false;
struct hostent *hostinfo;
memset(&server_name, 0, sizeof(server_name));
hostinfo = gethostbyname( hostname.ascii() );
if ( !hostinfo ) {
warning("Unknown host %s.\n", hostname.ascii());
return false;
}
get_sin_family(server_name) = domain;
get_sin_port(server_name) = htons(port);
memcpy(&get_sin_addr(server_name), hostinfo->h_addr_list[0], hostinfo->h_length);
return true;
}
/*
* Connects the PF_UNIX domain socket to _path.
*/
kdelibs'KSocket::connect() (./kdelibs/kdecore/ksock.cpp:206)
bool KSocket::connect( const char *_path )
{
if ( domain != PF_UNIX )
fatal( "Connecting a PF_INET socket to a PF_UNIX domain socket\n");
sock = ::socket(PF_UNIX,SOCK_STREAM,0);
if (sock < 0)
return false;
unix_addr.sun_family = AF_UNIX;
int l = strlen( _path );
if ( l > UNIX_PATH_MAX - 1 )
{
warning( "Too long PF_UNIX domain name '%s'\n",_path);
return false;
}
strcpy( unix_addr.sun_path, _path );
if ( 0 > ::connect( sock, (struct sockaddr*)(&unix_addr),
sizeof( unix_addr ) ) )
{
::close( sock );
sock = -1;
return false;
}
return true;
}
/*
* Connects the socket to _host, _port.
*/
kdelibs'KSocket::connect() (./kdelibs/kdecore/ksock.cpp:238)
bool KSocket::connect( const QString& _host, unsigned short int _port )
{
#ifdef INET6
if ( (domain != PF_INET6) && (domain != PF_INET) )
#else
if ( domain != PF_INET )
#endif
fatal( "Connecting a PF_UNIX domain socket to a PF_INET domain socket\n");
sock = ::socket(domain, SOCK_STREAM, 0);
if (sock < 0)
return false;
if ( !init_sockaddr( _host, _port) ) {
::close( sock );
sock = -1;
return false;
}
fcntl(sock, F_SETFL, ( fcntl(sock,F_GETFL)|O_NDELAY) );
errno = 0;
if (::connect(sock, (struct sockaddr*)(&server_name), sizeof(server_name))){
if(errno != EINPROGRESS && errno != EWOULDBLOCK) {
::close( sock );
sock = -1;
return false;
}
} else
return true;
fd_set rd, wr;
struct timeval timeout;
int n = timeOut*10; // Timeout in 1/10th's of a second
while(n--){
FD_ZERO(&rd);
FD_ZERO(&wr);
FD_SET(sock, &rd);
FD_SET(sock, &wr);
timeout.tv_usec = 100*1000; // 1/10th sec
timeout.tv_sec = 0;
select(sock + 1, &rd, &wr, (fd_set *)0, &timeout);
if (FD_ISSET(sock, &rd) || FD_ISSET(sock, &wr))
{
int errcode;
ksize_t len = sizeof(errcode);
int ret = getsockopt(sock, SOL_SOCKET, SO_ERROR, (char*)&errcode, &len);
if ((ret == -1) || (errcode != 0))
{
::close(sock);
sock = -1;
return false;
}
return true;
}
qApp->processEvents();
qApp->flushX();
}
warning("Timeout connecting socket...\n");
::close( sock );
sock = -1;
return false;
}
kdelibs'KSocket::ipv4_addr() (./kdelibs/kdecore/ksock.cpp:306)
unsigned long KSocket::ipv4_addr()
{
if ( domain != PF_INET )
return 0;
sockaddr_in name; ksize_t len = sizeof(name);
getsockname(sock, (struct sockaddr *) &name, &len);
if (name.sin_family == AF_INET) // It's IPv4
return ntohl(name.sin_addr.s_addr);
#ifdef INET6
else if (name.sin_family == AF_INET6) // It's IPv6 Ah.
return 0;
#endif
else // We dunno what it is
return 0;
}
kdelibs'KSocket::initSockaddr() (./kdelibs/kdecore/ksock.cpp:323)
bool KSocket::initSockaddr (ksockaddr_in *server_name, const char *hostname, unsigned short int port, int domain)
{
struct hostent *hostinfo;
#ifdef INET6
if (domain == PF_INET6) {
server_name->sin6_family = domain;
server_name->sin6_port = htons( port );
} else
#endif
{
get_sin_pfamily(server_name) = domain;
get_sin_pport(server_name) = htons( port );
}
hostinfo = gethostbyname( hostname );
if ( hostinfo == 0L )
return false;
#ifdef INET6
if (domain == PF_INET6) {
server_name->sin6_family = hostinfo->h_addrtype;
memcpy(&server_name->sin6_addr, hostinfo->h_addr_list[0], hostinfo->h_length);
} else
#endif
{
get_sin_pfamily(server_name) = hostinfo->h_addrtype;
memcpy(&get_sin_paddr(server_name), hostinfo->h_addr_list[0], hostinfo->h_length);
}
return true;
}
kdelibs'KSocket::~KSocket() (./kdelibs/kdecore/ksock.cpp:356)
KSocket::~KSocket()
{
if ( readNotifier )
{
delete readNotifier;
}
if ( writeNotifier )
delete writeNotifier;
::close( sock );
}