ksock.cpp

来自「将konqueror浏览器移植到ARM9 2410中」· C++ 代码 · 共 461 行

CPP
461
字号
/* *  This file is part of the KDE libraries *  Copyright (C) 1997 Torben Weis (weis@kde.org) * *  $Id: ksock.cpp,v 1.79 2001/06/11 00:32:41 faure Exp $ * *  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., 59 Temple Place - Suite 330, *  Boston, MA 02111-1307, USA. **/#include <config.h>#include <sys/types.h>#include <sys/stat.h>// on Linux/libc5, this includes linux/socket.h where SOMAXCONN is defined#include <sys/socket.h>#include <sys/resource.h>#include <sys/time.h>#include <sys/un.h>#ifdef HAVE_SYS_SELECT_H#include <sys/select.h>#endifextern "C" {#include <netinet/in.h>#include <arpa/inet.h>}#include "kdebug.h"#include "ksock.h"#include "kextsock.h"#include "ksockaddr.h"#include "ksocks.h"extern "C" {#include <errno.h>#include <fcntl.h>#ifdef HAVE_GETADDRINFO#include <netdb.h>#endif// defines MAXDNAME under Solaris#include <arpa/nameser.h>#include <resolv.h>}#include <stdio.h>#include <stdlib.h>#include <string.h>#include <signal.h>#include <unistd.h>#include <assert.h>#ifdef HAVE_SYSENT_H#include <sysent.h>#endif#if TIME_WITH_SYS_TIME#include <time.h>#endif// Play it safe, use a reasonable default, if SOMAXCONN was nowhere defined.#ifndef SOMAXCONN#warning Your header files do not seem to support SOMAXCONN#define SOMAXCONN 5#endif#include <qapplication.h>#include <qsocketnotifier.h>#include "netsupp.h"		// leave this last// I moved this into here so we could accurately detect the domain, for// posterity.  Really.KSocket::KSocket( int _sock) : sock(_sock), readNotifier(0), writeNotifier(0){  struct sockaddr_in sin;  ksocklen_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.  KSocks::self()->getsockname(_sock, (struct sockaddr *)&sin, &len);  // Now that we've got the domain, remember it  domain = sin.sin_family;}KSocket::KSocket( const char *_host, unsigned short int _port, int _timeout ) :  sock( -1 ), domain( AF_UNSPEC ), readNotifier( 0L ), writeNotifier( 0L ){    timeOut = _timeout;    connect( _host, _port );}KSocket::KSocket( const char *_path ) :  sock( -1 ), domain( AF_UNSPEC ), readNotifier( 0L ), writeNotifier( 0L ){  connect( _path );}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 );}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 );}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 );}void KSocket::slotWrite( int ){  emit writeEvent( this );}/* * This function is not used */bool KSocket::init_sockaddr( const QString& /*hostname*/, unsigned short int /*port*/ ){  return false;}/* * Connects the PF_UNIX domain socket to _path. */bool KSocket::connect( const char *_path ){  KExtendedSocket ks(QString::null, _path, KExtendedSocket::unixSocket);  ks.connect();  sock = ks.fd();  ks.release();  /* In this case, we are sure domain is PF_UNIX */  domain = PF_UNIX;  return sock >= 0;}/* * Connects the socket to _host, _port. */bool KSocket::connect( const QString& _host, unsigned short int _port ){  KExtendedSocket ks(_host, _port, KExtendedSocket::inetSocket);  ks.setTimeout(timeOut, 0);  ks.connect();  sock = ks.fd();  if (sock >= 0)    {      const KSocketAddress *sa = ks.localAddress();      if (sa != NULL)	domain = sa->family();    }  ks.release();  return sock >= 0;}unsigned long KSocket::ipv4_addr(){  unsigned long retval = 0;  KSocketAddress *sa = KExtendedSocket::peerAddress(sock);  if (sa == NULL)    return 0;  if (sa->address() != NULL && (sa->address()->sa_family == PF_INET#ifdef PF_INET6				|| sa->address()->sa_family == PF_INET6#endif      ))    {      KInetSocketAddress *ksin = (KInetSocketAddress*)sa;      const sockaddr_in *sin = ksin->addressV4();      if (sin != NULL)	retval = *(unsigned long*)&sin->sin_addr; // I told you this was dumb    }  delete sa;  return retval;}bool KSocket::initSockaddr (ksockaddr_in *server_name, const char *hostname, unsigned short int port, int domain){  // This function is now IPv4 only  // if you want something better, you should use KExtendedSocket::lookup yourself  kdWarning(170) << "deprecated KSocket::initSockaddr called" << endl;  if (domain != PF_INET)    return false;  QList<KAddressInfo> list = KExtendedSocket::lookup(hostname, QString::number(port),						     KExtendedSocket::ipv4Socket);  list.setAutoDelete(true);  if (list.isEmpty())    return false;  memset(server_name, 0, sizeof(*server_name));  // We are sure that only KInetSocketAddress objects are in the list  KInetSocketAddress *sin = (KInetSocketAddress*)list.getFirst()->address();  if (sin == NULL)    return false;  memcpy(server_name, sin->addressV4(), sizeof(*server_name));  kdDebug(170) << "KSocket::initSockaddr: returning " << sin->pretty() << endl;  return true;}KSocket::~KSocket(){  delete readNotifier;  delete writeNotifier;  if (sock != -1) {    ::close( sock );  }}class KServerSocketPrivate {public:   bool bind;   QCString path;   unsigned short int port;   KExtendedSocket *ks;};KServerSocket::KServerSocket( const char *_path ) :  notifier( 0L ), sock( -1 ){  domain = PF_UNIX;  d = new KServerSocketPrivate();  d->bind = true;  init ( _path );}KServerSocket::KServerSocket( const char *_path, bool _bind ) :  notifier( 0L ), sock( -1 ){  domain = PF_UNIX;  d = new KServerSocketPrivate();  d->bind = _bind;  init ( _path );}KServerSocket::KServerSocket( unsigned short int _port ) :  notifier( 0L ), sock( -1 ){  d = new KServerSocketPrivate();  d->bind = true;  init ( _port );}KServerSocket::KServerSocket( unsigned short int _port, bool _bind ) :  notifier( 0L ), sock( -1 ), d(0){  d = new KServerSocketPrivate();  d->bind = _bind;  init ( _port );}bool KServerSocket::init( const char *_path ){  if ( domain != PF_UNIX )    return false;  unlink(_path );  d->path = _path;  KExtendedSocket *ks = new KExtendedSocket(QString::null, _path, KExtendedSocket::passiveSocket |					    KExtendedSocket::unixSocket);  d->ks = ks;  if (d->bind)    return bindAndListen();  return true;}bool KServerSocket::init( unsigned short int _port ){  d->port = _port;  KExtendedSocket *ks;  ks = new KExtendedSocket(QString::null, _port, KExtendedSocket::passiveSocket |			   KExtendedSocket::inetSocket);  d->ks = ks;  if (d->bind)    return bindAndListen();  return true;}  bool KServerSocket::bindAndListen(){  if (d == NULL || d->ks == NULL)    return false;  int ret = d->ks->listen( SOMAXCONN );  if (ret < 0)    {        kdWarning(170) << "Error listening on socket: " << ret << "\n";	delete d->ks;	d->ks = NULL;	sock = -1;	return false;    }  const KSocketAddress *sa = d->ks->localAddress();  if (sa != NULL)    domain = sa->family();  sock = d->ks->fd();  notifier = new QSocketNotifier( sock, QSocketNotifier::Read );  connect( notifier, SIGNAL( activated(int) ), this, SLOT( slotAccept(int) ) );  return true;}unsigned short int KServerSocket::port(){  if (d == NULL || d->ks == NULL || sock == -1)    return 0;  const KSocketAddress *sa = d->ks->localAddress();  if (sa == NULL)    return 0;  // we can use sockaddr_in here even if it isn't IPv4  sockaddr_in *sin = (sockaddr_in*)sa->address();  if (sin->sin_family == PF_INET)    // correct family    return sin->sin_port;#ifdef PF_INET6  else if (sin->sin_family == PF_INET6)    {      kde_sockaddr_in6 *sin6 = (kde_sockaddr_in6*)sin;      return sin6->sin6_port;    }#endif  return 0;			// not a port we know}unsigned long KServerSocket::ipv4_addr(){  if (d == NULL || d->ks == NULL || sock == -1)    return 0;  const KSocketAddress *sa = d->ks->localAddress();    const sockaddr_in *sin = (sockaddr_in*)sa->address();  if (sin->sin_family == PF_INET)    // correct family    return ntohl(*(unsigned long*)&sin->sin_addr);#ifdef PF_INET6  else if (sin->sin_family == PF_INET6)    {      KInetSocketAddress *ksin = (KInetSocketAddress*)sa;      sin = ksin->addressV4();      if (sin != NULL)	return *(unsigned long*)&sin->sin_addr;    }#endif  return 0;			// this is dumb, isn't it?}void KServerSocket::slotAccept( int ){  if (d == NULL || d->ks == NULL || sock == -1)    return;			// nothing!  KExtendedSocket *s;  if (d->ks->accept(s) < 0)    {        kdWarning(170) << "Error accepting\n";        return;    }    int new_sock = s->fd();  s->release();			// we're getting rid of the KExtendedSocket  delete s;  emit accepted( new KSocket( new_sock ) );}KServerSocket::~KServerSocket(){  delete notifier;  if (d != NULL)    {      if (d->ks != NULL)	delete d->ks;      delete d;    }  // deleting d->ks closes the socket  //  ::close( sock );}#include "ksock.moc"

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?