⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qnativesocketengine_unix.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the QtNetwork module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file.  Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************///#define QNATIVESOCKETENGINE_DEBUG#include "qplatformdefs.h"#include "qnativesocketengine_p.h"#include "qiodevice.h"#include "qhostaddress.h"#include "qvarlengtharray.h"#include <time.h>#include <errno.h>#include <fcntl.h>#ifndef QT_NO_IPV6IFNAME#include <net/if.h>#endif#ifndef QT_NO_IPV6IFNAME#include <net/if.h>#endif#ifdef QT_LSB#include <arpa/inet.h>#endif//#define QNATIVESOCKETENGINE_DEBUG#if defined QNATIVESOCKETENGINE_DEBUG#include <qstring.h>#include <ctype.h>/*    Returns a human readable representation of the first \a len    characters in \a data.*/static QByteArray qt_prettyDebug(const char *data, int len, int maxSize){    if (!data) return "(null)";    QByteArray out;    for (int i = 0; i < len; ++i) {        char c = data[i];        if (isprint(c)) {            out += c;        } else switch (c) {        case '\n': out += "\\n"; break;        case '\r': out += "\\r"; break;        case '\t': out += "\\t"; break;        default:            QString tmp;            tmp.sprintf("\\%o", c);            out += tmp.toLatin1();        }    }    if (len < maxSize)        out += "...";    return out;}#endif// Almost always the same. If not, specify in qplatformdefs.h.#if !defined(QT_SOCKOPTLEN_T)# define QT_SOCKOPTLEN_T QT_SOCKLEN_T#endif// Tru64 redefines accept -> _accept with _XOPEN_SOURCE_EXTENDEDstatic inline int qt_socket_accept(int s, struct sockaddr *addr, QT_SOCKLEN_T *addrlen){ return ::accept(s, addr, static_cast<QT_SOCKLEN_T *>(addrlen)); }#if defined(accept)# undef accept#endif// UnixWare 7 redefines listen -> _listenstatic inline int qt_socket_listen(int s, int backlog){ return ::listen(s, backlog); }#if defined(listen)# undef listen#endif// UnixWare 7 redefines socket -> _socketstatic inline int qt_socket_socket(int domain, int type, int protocol){ return ::socket(domain, type, protocol); }#if defined(socket)# undef socket#endifstatic void qt_ignore_sigpipe(){    // Set to ignore SIGPIPE once only.    static QBasicAtomic atom = Q_ATOMIC_INIT(0);    if (atom.testAndSet(0, 1)) {        struct sigaction noaction;        memset(&noaction, 0, sizeof(noaction));        noaction.sa_handler = SIG_IGN;        ::sigaction(SIGPIPE, &noaction, 0);    }}/*    Extracts the port and address from a sockaddr, and stores them in    \a port and \a addr if they are non-null.*/static inline void qt_socket_getPortAndAddress(struct sockaddr *sa, quint16 *port, QHostAddress *addr){#if !defined(QT_NO_IPV6)    if (sa->sa_family == AF_INET6) {        struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)sa;        Q_IPV6ADDR tmp;        memcpy(&tmp, &sa6->sin6_addr.s6_addr, sizeof(tmp));        if (addr) {            QHostAddress tmpAddress;            tmpAddress.setAddress(tmp);            *addr = tmpAddress;#ifndef QT_NO_IPV6IFNAME            char scopeid[IFNAMSIZ];            if (::if_indextoname(sa6->sin6_scope_id, scopeid) > 0) {                addr->setScopeId(QLatin1String(scopeid));            } else#endif            addr->setScopeId(QString::number(sa6->sin6_scope_id));        }        if (port)            *port = ntohs(sa6->sin6_port);        return;    }#endif    struct sockaddr_in *sa4 = (struct sockaddr_in *)sa;    if (port)        *port = ntohs(sa4->sin_port);    if (addr) {        QHostAddress tmpAddress;        tmpAddress.setAddress(ntohl(sa4->sin_addr.s_addr));        *addr = tmpAddress;    }}/*! \internal    Creates and returns a new socket descriptor of type \a socketType    and \a socketProtocol.  Returns -1 on failure.*/bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType socketType,                                         QAbstractSocket::NetworkLayerProtocol socketProtocol){#ifndef QT_NO_IPV6    int protocol = (socketProtocol == QAbstractSocket::IPv6Protocol) ? AF_INET6 : AF_INET;#else    Q_UNUSED(socketProtocol);    int protocol = AF_INET;#endif    int type = (socketType == QAbstractSocket::UdpSocket) ? SOCK_DGRAM : SOCK_STREAM;    int socket = qt_socket_socket(protocol, type, 0);    if (socket <= 0) {        switch (errno) {        case EPROTONOSUPPORT:        case EAFNOSUPPORT:        case EINVAL:            setError(QAbstractSocket::UnsupportedSocketOperationError, ProtocolUnsupportedErrorString);            break;        case ENFILE:        case EMFILE:        case ENOBUFS:        case ENOMEM:            setError(QAbstractSocket::SocketResourceError, ResourceErrorString);            break;        case EACCES:            setError(QAbstractSocket::SocketAccessError, AccessErrorString);            break;        default:            break;        }        return false;    }    // Ensure that the socket is closed on exec*().    ::fcntl(socket, F_SETFD, FD_CLOEXEC);    socketDescriptor = socket;    return true;}/*    Returns the value of the socket option \a opt.*/int QNativeSocketEnginePrivate::option(QNativeSocketEngine::SocketOption opt) const{    Q_Q(const QNativeSocketEngine);    if (!q->isValid())        return -1;    int n = -1;    switch (opt) {    case QNativeSocketEngine::ReceiveBufferSocketOption:        n = SO_RCVBUF;        break;    case QNativeSocketEngine::SendBufferSocketOption:        n = SO_SNDBUF;        break;    case QNativeSocketEngine::NonBlockingSocketOption:        break;    case QNativeSocketEngine::BroadcastSocketOption:        break;    case QNativeSocketEngine::AddressReusable:        n = SO_REUSEADDR;        break;    case QNativeSocketEngine::BindExclusively:        return true;    case QNativeSocketEngine::ReceiveOutOfBandData:        n = SO_OOBINLINE;        break;    }    int v = -1;    QT_SOCKOPTLEN_T len = sizeof(v);    if (getsockopt(socketDescriptor, SOL_SOCKET, n, (char *) &v, &len) != -1)        return v;    return -1;}/*    Sets the socket option \a opt to \a v.*/bool QNativeSocketEnginePrivate::setOption(QNativeSocketEngine::SocketOption opt, int v){    Q_Q(QNativeSocketEngine);    if (!q->isValid())        return false;    int n = 0;    switch (opt) {    case QNativeSocketEngine::ReceiveBufferSocketOption:        n = SO_RCVBUF;        break;    case QNativeSocketEngine::SendBufferSocketOption:        n = SO_SNDBUF;        break;    case QNativeSocketEngine::BroadcastSocketOption:        n = SO_BROADCAST;        break;    case QNativeSocketEngine::NonBlockingSocketOption: {        // Make the socket nonblocking.        int flags = ::fcntl(socketDescriptor, F_GETFL, 0);        if (flags == -1) {#ifdef QNATIVESOCKETENGINE_DEBUG            perror("QNativeSocketEnginePrivate::setOption(): fcntl(F_GETFL) failed");#endif            return false;        }        if (::fcntl(socketDescriptor, F_SETFL, flags | O_NONBLOCK) == -1) {#ifdef QNATIVESOCKETENGINE_DEBUG            perror("QNativeSocketEnginePrivate::setOption(): fcntl(F_SETFL) failed");#endif            return false;        }        return true;    }    case QNativeSocketEngine::AddressReusable:#ifdef SO_REUSEPORT        n = SO_REUSEPORT;#else        n = SO_REUSEADDR;#endif        break;    case QNativeSocketEngine::BindExclusively:        return true;    case QNativeSocketEngine::ReceiveOutOfBandData:        n = SO_OOBINLINE;        break;    }    return ::setsockopt(socketDescriptor, SOL_SOCKET, n, (char *) &v, sizeof(v)) == 0;}bool QNativeSocketEnginePrivate::nativeConnect(const QHostAddress &addr, quint16 port){    struct sockaddr_in sockAddrIPv4;    struct sockaddr *sockAddrPtr = 0;    QT_SOCKLEN_T sockAddrSize = 0;#if !defined(QT_NO_IPV6)    struct sockaddr_in6 sockAddrIPv6;    if (addr.protocol() == QAbstractSocket::IPv6Protocol) {        memset(&sockAddrIPv6, 0, sizeof(sockAddrIPv6));        sockAddrIPv6.sin6_family = AF_INET6;        sockAddrIPv6.sin6_port = htons(port);#ifndef QT_NO_IPV6IFNAME        sockAddrIPv6.sin6_scope_id = ::if_nametoindex(addr.scopeId().toLatin1().data());#else        sockAddrIPv6.sin6_scope_id = addr.scopeId().toInt();#endif        Q_IPV6ADDR ip6 = addr.toIPv6Address();        memcpy(&sockAddrIPv6.sin6_addr.s6_addr, &ip6, sizeof(ip6));        sockAddrSize = sizeof(sockAddrIPv6);        sockAddrPtr = (struct sockaddr *) &sockAddrIPv6;    } else#if 0    {}#endif#endif    if (addr.protocol() == QAbstractSocket::IPv4Protocol) {        memset(&sockAddrIPv4, 0, sizeof(sockAddrIPv4));        sockAddrIPv4.sin_family = AF_INET;        sockAddrIPv4.sin_port = htons(port);        sockAddrIPv4.sin_addr.s_addr = htonl(addr.toIPv4Address());        sockAddrSize = sizeof(sockAddrIPv4);        sockAddrPtr = (struct sockaddr *) &sockAddrIPv4;    } else {        // unreachable    }    int connectResult = QT_SOCKET_CONNECT(socketDescriptor, sockAddrPtr, sockAddrSize);    if (connectResult == -1) {        switch (errno) {        case EISCONN:            socketState = QAbstractSocket::ConnectedState;            break;        case ECONNREFUSED:        case EINVAL:            setError(QAbstractSocket::ConnectionRefusedError, ConnectionRefusedErrorString);            socketState = QAbstractSocket::UnconnectedState;            break;        case ETIMEDOUT:            setError(QAbstractSocket::NetworkError, ConnectionTimeOutErrorString);            break;        case EHOSTUNREACH:            setError(QAbstractSocket::NetworkError, HostUnreachableErrorString);            socketState = QAbstractSocket::UnconnectedState;            break;        case ENETUNREACH:            setError(QAbstractSocket::NetworkError, NetworkUnreachableErrorString);            socketState = QAbstractSocket::UnconnectedState;            break;        case EADDRINUSE:            setError(QAbstractSocket::NetworkError, AddressInuseErrorString);            break;        case EINPROGRESS:        case EALREADY:            setError(QAbstractSocket::UnfinishedSocketOperationError, InvalidSocketErrorString);            socketState = QAbstractSocket::ConnectingState;            break;        case EAGAIN:            setError(QAbstractSocket::UnfinishedSocketOperationError, InvalidSocketErrorString);            setError(QAbstractSocket::SocketResourceError, ResourceErrorString);            break;        case EACCES:        case EPERM:            setError(QAbstractSocket::SocketAccessError, AccessErrorString);            socketState = QAbstractSocket::UnconnectedState;            break;        case EAFNOSUPPORT:        case EBADF:        case EFAULT:        case ENOTSOCK:            socketState = QAbstractSocket::UnconnectedState;        default:            break;        }        if (socketState != QAbstractSocket::ConnectedState) {#if defined (QNATIVESOCKETENGINE_DEBUG)            qDebug("QNativeSocketEnginePrivate::nativeConnect(%s, %i) == false (%s)",                   addr.toString().toLatin1().constData(), port,                   socketState == QAbstractSocket::ConnectingState                   ? "Connection in progress" : socketErrorString.toLatin1().constData());#endif            return false;        }    }#if defined (QNATIVESOCKETENGINE_DEBUG)    qDebug("QNativeSocketEnginePrivate::nativeConnect(%s, %i) == true",           addr.toString().toLatin1().constData(), port);#endif    socketState = QAbstractSocket::ConnectedState;    return true;}bool QNativeSocketEnginePrivate::nativeBind(const QHostAddress &address, quint16 port){    struct sockaddr_in sockAddrIPv4;    struct sockaddr *sockAddrPtr = 0;    QT_SOCKLEN_T sockAddrSize = 0;#if !defined(QT_NO_IPV6)    struct sockaddr_in6 sockAddrIPv6;    if (address.protocol() == QAbstractSocket::IPv6Protocol) {        memset(&sockAddrIPv6, 0, sizeof(sockAddrIPv6));        sockAddrIPv6.sin6_family = AF_INET6;        sockAddrIPv6.sin6_port = htons(port);#ifndef QT_NO_IPV6IFNAME        sockAddrIPv6.sin6_scope_id = ::if_nametoindex(address.scopeId().toLatin1().data());#else        sockAddrIPv6.sin6_scope_id = address.scopeId().toInt();#endif        Q_IPV6ADDR tmp = address.toIPv6Address();        memcpy(&sockAddrIPv6.sin6_addr.s6_addr, &tmp, sizeof(tmp));        sockAddrSize = sizeof(sockAddrIPv6);        sockAddrPtr = (struct sockaddr *) &sockAddrIPv6;    } else#endif        if (address.protocol() == QAbstractSocket::IPv4Protocol) {            memset(&sockAddrIPv4, 0, sizeof(sockAddrIPv4));            sockAddrIPv4.sin_family = AF_INET;            sockAddrIPv4.sin_port = htons(port);            sockAddrIPv4.sin_addr.s_addr = htonl(address.toIPv4Address());            sockAddrSize = sizeof(sockAddrIPv4);            sockAddrPtr = (struct sockaddr *) &sockAddrIPv4;        } else {            // unreachable        }    int bindResult = QT_SOCKET_BIND(socketDescriptor, sockAddrPtr, sockAddrSize);    if (bindResult < 0) {        switch(errno) {        case EADDRINUSE:            setError(QAbstractSocket::AddressInUseError, AddressInuseErrorString);            break;        case EACCES:            setError(QAbstractSocket::SocketAccessError, AddressProtectedErrorString);            break;

⌨️ 快捷键说明

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