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

📄 qnativesocketengine_unix.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 2 页
字号:
        case EINVAL:            setError(QAbstractSocket::UnsupportedSocketOperationError, OperationUnsupportedErrorString);            break;        case EADDRNOTAVAIL:            setError(QAbstractSocket::SocketAddressNotAvailableError, AddressNotAvailableErrorString);            break;        default:            break;        }#if defined (QNATIVESOCKETENGINE_DEBUG)        qDebug("QNativeSocketEnginePrivate::nativeBind(%s, %i) == false (%s)",               address.toString().toLatin1().constData(), port, socketErrorString.toLatin1().constData());#endif        return false;    }#if defined (QNATIVESOCKETENGINE_DEBUG)    qDebug("QNativeSocketEnginePrivate::nativeBind(%s, %i) == true",           address.toString().toLatin1().constData(), port);#endif    socketState = QAbstractSocket::BoundState;    return true;}bool QNativeSocketEnginePrivate::nativeListen(int backlog){    if (qt_socket_listen(socketDescriptor, backlog) < 0) {        switch (errno) {        case EADDRINUSE:            setError(QAbstractSocket::AddressInUseError,                     PortInuseErrorString);            break;        default:            break;        }#if defined (QNATIVESOCKETENGINE_DEBUG)        qDebug("QNativeSocketEnginePrivate::nativeListen(%i) == false (%s)",               backlog, socketErrorString.toLatin1().constData());#endif        return false;    }#if defined (QNATIVESOCKETENGINE_DEBUG)    qDebug("QNativeSocketEnginePrivate::nativeListen(%i) == true", backlog);#endif    socketState = QAbstractSocket::ListeningState;    return true;}int QNativeSocketEnginePrivate::nativeAccept(){    int acceptedDescriptor = qt_socket_accept(socketDescriptor, 0, 0);#if defined (QNATIVESOCKETENGINE_DEBUG)    qDebug("QNativeSocketEnginePrivate::nativeAccept() == %i", acceptedDescriptor);#endif    // Ensure that the socket is closed on exec*()    ::fcntl(acceptedDescriptor, F_SETFD, FD_CLOEXEC);    return acceptedDescriptor;}qint64 QNativeSocketEnginePrivate::nativeBytesAvailable() const{    /*      Apparently, there is not consistency among different operating      systems on how to use FIONREAD.      FreeBSD, Linux and Solaris all expect the 3rd argument to      ioctl() to be an int, which is normally 32-bit even on 64-bit      machines.      IRIX, on the other hand, expects a size_t, which is 64-bit on      64-bit machines.      So, the solution is to use size_t initialized to zero to make      sure all bits are set to zero, preventing underflow with the      FreeBSD/Linux/Solaris ioctls.    */    size_t nbytes = 0;    // gives shorter than true amounts on Unix domain sockets.    qint64 available = 0;    if (::ioctl(socketDescriptor, FIONREAD, (char *) &nbytes) >= 0)        available = (qint64) *((int *) &nbytes);#if defined (QNATIVESOCKETENGINE_DEBUG)    qDebug("QNativeSocketEnginePrivate::nativeBytesAvailable() == %lli", available);#endif    return available;}bool QNativeSocketEnginePrivate::nativeHasPendingDatagrams() const{    // Create a sockaddr struct and reset its port number.#if !defined(QT_NO_IPV6)    struct sockaddr_storage storage;    sockaddr_in6 *storagePtrIPv6 = reinterpret_cast<sockaddr_in6 *>(&storage);    storagePtrIPv6->sin6_port = 0;#else    struct sockaddr storage;#endif    sockaddr *storagePtr = reinterpret_cast<sockaddr *>(&storage);    storagePtr->sa_family = 0;    sockaddr_in *storagePtrIPv4 = reinterpret_cast<sockaddr_in *>(&storage);    storagePtrIPv4->sin_port = 0;    QT_SOCKLEN_T storageSize = sizeof(storage);    // Peek 0 bytes into the next message. The size of the message may    // well be 0, so we can't check recvfrom's return value.    ssize_t readBytes;    do {        char c;        readBytes = ::recvfrom(socketDescriptor, &c, 1, MSG_PEEK, storagePtr, &storageSize);    } while (readBytes == -1 && errno == EINTR);    // If there's no error, or if our buffer was too small, there must be a    // pending datagram.    bool result = (readBytes != -1) || errno == EMSGSIZE;#if defined (QNATIVESOCKETENGINE_DEBUG)    qDebug("QNativeSocketEnginePrivate::nativeHasPendingDatagrams() == %s",           result ? "true" : "false");#endif    return result;}qint64 QNativeSocketEnginePrivate::nativePendingDatagramSize() const{    QVarLengthArray<char, 8192> udpMessagePeekBuffer(8192);    ssize_t recvResult = -1;    for (;;) {        // the data written to udpMessagePeekBuffer is discarded, so        // this function is still reentrant although it might not look        // so.        recvResult = ::recv(socketDescriptor, udpMessagePeekBuffer.data(),                            udpMessagePeekBuffer.size(), MSG_PEEK);        if (recvResult == -1 && errno == EINTR)            continue;        if (recvResult != (ssize_t) udpMessagePeekBuffer.size())            break;        udpMessagePeekBuffer.resize(udpMessagePeekBuffer.size() * 2);    }#if defined (QNATIVESOCKETENGINE_DEBUG)    qDebug("QNativeSocketEnginePrivate::nativePendingDatagramSize() == %i", recvResult);#endif    return qint64(recvResult);}qint64 QNativeSocketEnginePrivate::nativeReceiveDatagram(char *data, qint64 maxSize,                                                    QHostAddress *address, quint16 *port){#if !defined(QT_NO_IPV6)    struct sockaddr_storage aa;#else    struct sockaddr_in aa;#endif    memset(&aa, 0, sizeof(aa));    QT_SOCKLEN_T sz;    sz = sizeof(aa);    ssize_t recvFromResult = 0;    do {        char c;        recvFromResult = ::recvfrom(socketDescriptor, maxSize ? data : &c, maxSize ? maxSize : 1,                                    0, (struct sockaddr *)&aa, &sz);    } while (recvFromResult == -1 && errno == EINTR);    if (recvFromResult == -1) {        setError(QAbstractSocket::NetworkError, ReceiveDatagramErrorString);    } else if (port || address) {        qt_socket_getPortAndAddress((struct sockaddr *) &aa, port, address);    }#if defined (QNATIVESOCKETENGINE_DEBUG)    qDebug("QNativeSocketEnginePrivate::nativeReceiveDatagram(%p \"%s\", %lli, %s, %i) == %lli",           data, qt_prettyDebug(data, qMin(recvFromResult, ssize_t(16)), recvFromResult).data(), maxSize,           address ? address->toString().toLatin1().constData() : "(nil)",           port ? *port : 0, (qint64) recvFromResult);#endif    return qint64(maxSize ? recvFromResult : recvFromResult == -1 ? -1 : 0);}qint64 QNativeSocketEnginePrivate::nativeSendDatagram(const char *data, qint64 len,                                                   const QHostAddress &host, 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 (host.protocol() == QAbstractSocket::IPv6Protocol) {	memset(&sockAddrIPv6, 0, sizeof(sockAddrIPv6));	sockAddrIPv6.sin6_family = AF_INET6;	sockAddrIPv6.sin6_port = htons(port);	Q_IPV6ADDR tmp = host.toIPv6Address();	memcpy(&sockAddrIPv6.sin6_addr.s6_addr, &tmp, sizeof(tmp));	sockAddrSize = sizeof(sockAddrIPv6);	sockAddrPtr = (struct sockaddr *)&sockAddrIPv6;    } else#endif    if (host.protocol() == QAbstractSocket::IPv4Protocol) {	memset(&sockAddrIPv4, 0, sizeof(sockAddrIPv4));	sockAddrIPv4.sin_family = AF_INET;	sockAddrIPv4.sin_port = htons(port);	sockAddrIPv4.sin_addr.s_addr = htonl(host.toIPv4Address());	sockAddrSize = sizeof(sockAddrIPv4);	sockAddrPtr = (struct sockaddr *)&sockAddrIPv4;    }    // ignore the SIGPIPE signal    qt_ignore_sigpipe();    ssize_t sentBytes;    do {        sentBytes = ::sendto(socketDescriptor, data, len,                             0, sockAddrPtr, sockAddrSize);    } while (sentBytes == -1 && errno == EINTR);    if (sentBytes < 0) {        switch (errno) {        case EMSGSIZE:            setError(QAbstractSocket::DatagramTooLargeError, DatagramTooLargeErrorString);            break;        default:            setError(QAbstractSocket::NetworkError, SendDatagramErrorString);        }    }#if defined (QNATIVESOCKETENGINE_DEBUG)    qDebug("QNativeSocketEngine::sendDatagram(%p \"%s\", %lli, \"%s\", %i) == %lli", data,           qt_prettyDebug(data, qMin<int>(len, 16), len).data(), len, host.toString().toLatin1().constData(),           port, (qint64) sentBytes);#endif    return qint64(sentBytes);}bool QNativeSocketEnginePrivate::fetchConnectionParameters(){    localPort = 0;    localAddress.clear();    peerPort = 0;    peerAddress.clear();    if (socketDescriptor == -1)        return false;#if !defined(QT_NO_IPV6)    struct sockaddr_storage sa;#else    struct sockaddr_in sa;#endif    struct sockaddr *sockAddrPtr = (struct sockaddr *) &sa;    QT_SOCKLEN_T sockAddrSize = sizeof(sa);    // Determine local address    memset(&sa, 0, sizeof(sa));    if (::getsockname(socketDescriptor, sockAddrPtr, &sockAddrSize) == 0) {        qt_socket_getPortAndAddress(sockAddrPtr, &localPort, &localAddress);        // Determine protocol family        switch (sockAddrPtr->sa_family) {        case AF_INET:            socketProtocol = QAbstractSocket::IPv4Protocol;            break;#if !defined (QT_NO_IPV6)        case AF_INET6:            socketProtocol = QAbstractSocket::IPv6Protocol;            break;#endif        default:            socketProtocol = QAbstractSocket::UnknownNetworkLayerProtocol;            break;        }    } else if (errno == EBADF) {        setError(QAbstractSocket::UnsupportedSocketOperationError, InvalidSocketErrorString);        return false;    }    // Determine the remote address    if (!::getpeername(socketDescriptor, sockAddrPtr, &sockAddrSize))        qt_socket_getPortAndAddress(sockAddrPtr, &peerPort, &peerAddress);    // Determine the socket type (UDP/TCP)    int value = 0;    QT_SOCKOPTLEN_T valueSize = sizeof(int);    if (::getsockopt(socketDescriptor, SOL_SOCKET, SO_TYPE, &value, &valueSize) == 0) {        if (value == SOCK_STREAM)            socketType = QAbstractSocket::TcpSocket;        else if (value == SOCK_DGRAM)            socketType = QAbstractSocket::UdpSocket;        else            socketType = QAbstractSocket::UnknownSocketType;    }#if defined (QNATIVESOCKETENGINE_DEBUG)    QString socketProtocolStr = "UnknownProtocol";    if (socketProtocol == QAbstractSocket::IPv4Protocol) socketProtocolStr = "IPv4Protocol";    else if (socketProtocol == QAbstractSocket::IPv6Protocol) socketProtocolStr = "IPv6Protocol";    QString socketTypeStr = "UnknownSocketType";    if (socketType == QAbstractSocket::TcpSocket) socketTypeStr = "TcpSocket";    else if (socketType == QAbstractSocket::UdpSocket) socketTypeStr = "UdpSocket";    qDebug("QNativeSocketEnginePrivate::fetchConnectionParameters() local == %s:%i,"           " peer == %s:%i, socket == %s - %s",           localAddress.toString().toLatin1().constData(), localPort,           peerAddress.toString().toLatin1().constData(), peerPort,socketTypeStr.toLatin1().constData(),           socketProtocolStr.toLatin1().constData());#endif    return true;}void QNativeSocketEnginePrivate::nativeClose(){#if defined (QNATIVESOCKETENGINE_DEBUG)    qDebug("QNativeSocketEngine::nativeClose()");#endif    ::close(socketDescriptor);}qint64 QNativeSocketEnginePrivate::nativeWrite(const char *data, qint64 len){    Q_Q(QNativeSocketEngine);    // ignore the SIGPIPE signal    qt_ignore_sigpipe();    // loop while ::write() returns -1 and errno == EINTR, in case    // of an interrupting signal.    ssize_t writtenBytes;    do {        writtenBytes = ::write(socketDescriptor, data, len);    } while (writtenBytes < 0 && errno == EINTR);    if (writtenBytes < 0) {        switch (errno) {        case EPIPE:        case ECONNRESET:            writtenBytes = -1;            setError(QAbstractSocket::RemoteHostClosedError, RemoteHostClosedErrorString);            q->close();            break;        case EAGAIN:            writtenBytes = 0;            break;        case EMSGSIZE:            setError(QAbstractSocket::DatagramTooLargeError, DatagramTooLargeErrorString);            break;        default:            break;        }    }#if defined (QNATIVESOCKETENGINE_DEBUG)    qDebug("QNativeSocketEnginePrivate::nativeWrite(%p \"%s\", %llu) == %i",           data, qt_prettyDebug(data, qMin((int) len, 16),                                (int) len).data(), len, (int) writtenBytes);#endif    return qint64(writtenBytes);}/**/qint64 QNativeSocketEnginePrivate::nativeRead(char *data, qint64 maxSize){    Q_Q(QNativeSocketEngine);    if (!q->isValid()) {        qWarning("QNativeSocketEngine::unbufferedRead: Invalid socket");        return -1;    }    ssize_t r = 0;    do {        r = ::read(socketDescriptor, data, maxSize);    } while (r == -1 && errno == EINTR);    if (r < 0) {        r = -1;        switch (errno) {#if EWOULDBLOCK-0 && EWOULDBLOCK != EAGAIN        case EWOULDBLOCK:#endif        case EAGAIN:            // No data was available for reading            r = -2;            break;        case EBADF:        case EINVAL:        case EIO:            setError(QAbstractSocket::NetworkError, ReadErrorString);            break;        case ECONNRESET:            r = 0;            break;        default:            break;        }    }#if defined (QNATIVESOCKETENGINE_DEBUG)    qDebug("QNativeSocketEnginePrivate::nativeRead(%p \"%s\", %llu) == %i",           data, qt_prettyDebug(data, qMin(r, ssize_t(16)), r).data(),           maxSize, r);#endif    return qint64(r);}int QNativeSocketEnginePrivate::nativeSelect(int timeout, bool selectForRead) const{    fd_set fds;    FD_ZERO(&fds);    FD_SET(socketDescriptor, &fds);    struct timeval tv;    tv.tv_sec = timeout / 1000;    tv.tv_usec = (timeout % 1000) * 1000;    if (selectForRead)        return select(socketDescriptor + 1, &fds, 0, 0, timeout < 0 ? 0 : &tv);    else        return select(socketDescriptor + 1, 0, &fds, 0, timeout < 0 ? 0 : &tv);}int QNativeSocketEnginePrivate::nativeSelect(int timeout, bool checkRead, bool checkWrite,				      bool *selectForRead, bool *selectForWrite) const{    fd_set fdread;    FD_ZERO(&fdread);    if (checkRead)        FD_SET(socketDescriptor, &fdread);    fd_set fdwrite;    FD_ZERO(&fdwrite);    if (checkWrite)        FD_SET(socketDescriptor, &fdwrite);    struct timeval tv;    tv.tv_sec = timeout / 1000;    tv.tv_usec = (timeout % 1000) * 1000;    int ret = select(socketDescriptor + 1, &fdread, &fdwrite, 0, timeout < 0 ? 0 : &tv);    if (ret <= 0)        return ret;    *selectForRead = FD_ISSET(socketDescriptor, &fdread);    *selectForWrite = FD_ISSET(socketDescriptor, &fdwrite);    return ret;}

⌨️ 快捷键说明

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