ksock.cpp
来自「konqueror3 embedded版本, KDE环境下的当家浏览器的嵌入式版」· C++ 代码 · 共 436 行
CPP
436 行
/* * This file is part of the KDE libraries * Copyright (C) 1997 Torben Weis (weis@kde.org) * * $Id: ksock.cpp 482738 2005-11-24 00:21:15Z mueller $ * * 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. **/#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>}#define KSOCK_NO_BROKEN#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#ifdef __CYGWIN__#include "qwindowdefs.h"#endif class KSocketPrivate{public: QSocketNotifier *readNotifier; QSocketNotifier *writeNotifier; KSocketPrivate() : readNotifier(0), writeNotifier(0) { }};// I moved this into here so we could accurately detect the domain, for// posterity. Really.KSocket::KSocket( int _sock) : sock(_sock), d(new KSocketPrivate){ struct sockaddr_in sin; ksocklen_t len = sizeof(sin); memset(&sin, 0, len); // getsockname will fill in all the appropriate 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);}KSocket::KSocket( const char *_host, unsigned short int _port, int _timeout ) : sock( -1 ), d(new KSocketPrivate){ connect( _host, _port, _timeout );}KSocket::KSocket( const char *_path ) : sock( -1 ), d(new KSocketPrivate){ connect( _path );}void KSocket::enableRead( bool _state ){ if ( _state ) { if ( !d->readNotifier ) { d->readNotifier = new QSocketNotifier( sock, QSocketNotifier::Read ); QObject::connect( d->readNotifier, SIGNAL( activated(int) ), this, SLOT( slotRead(int) ) ); } else d->readNotifier->setEnabled( true ); } else if ( d->readNotifier ) d->readNotifier->setEnabled( false );}void KSocket::enableWrite( bool _state ){ if ( _state ) { if ( !d->writeNotifier ) { d->writeNotifier = new QSocketNotifier( sock, QSocketNotifier::Write ); QObject::connect( d->writeNotifier, SIGNAL( activated(int) ), this, SLOT( slotWrite(int) ) ); } else d->writeNotifier->setEnabled( true ); } else if ( d->writeNotifier ) d->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 );}/* * 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(); return sock >= 0;}/* * Connects the socket to _host, _port. */bool KSocket::connect( const QString& _host, unsigned short int _port, int _timeout ){ KExtendedSocket ks(_host, _port, KExtendedSocket::inetSocket); ks.setTimeout(_timeout, 0); ks.connect(); sock = ks.fd(); ks.release(); return sock >= 0;}// only for doxygen - the define is always true as defined above#ifdef KSOCK_NO_BROKENunsigned 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 = sin->sin_addr.s_addr; } 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; QPtrList<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;}#endifKSocket::~KSocket(){ // Coolo says delete 0 is ok :) -thiago delete d->readNotifier; delete d->writeNotifier; delete d; if (sock != -1) { ::close( sock ); }}class KServerSocketPrivate{public: bool bind; QCString path; unsigned short int port; KExtendedSocket *ks;};KServerSocket::KServerSocket( const char *_path, bool _bind ) : sock( -1 ){ d = new KServerSocketPrivate(); d->bind = _bind; init ( _path );}KServerSocket::KServerSocket( unsigned short int _port, bool _bind ) : sock( -1 ){ d = new KServerSocketPrivate(); d->bind = _bind; init ( _port );}bool KServerSocket::init( const char *_path ){ 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; } sock = d->ks->fd(); connect( d->ks->readNotifier(), 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(sin->sin_addr.s_addr);#ifdef PF_INET6 else if (sin->sin_family == PF_INET6) { KInetSocketAddress *ksin = (KInetSocketAddress*)sa; sin = ksin->addressV4(); if (sin != NULL) return sin->sin_addr.s_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(){ 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 + -
显示快捷键?