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

📄 qunixsocket.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/*!  Construct a QUnixSocket instance, with \a parent.  The read buffer is initially set to \a readBufferSize bytes, and the rights  buffer to \a rightsBufferSize entries.  \sa QUnixSocket::readBufferSize() QUnixSocket::rightsBufferSize()  */QUnixSocket::QUnixSocket(qint64 readBufferSize, qint64 rightsBufferSize,                         QObject * parent): QIODevice(parent), d(new QUnixSocketPrivate(this)){    Q_ASSERT(readBufferSize > 0 && rightsBufferSize >= 0);    setOpenMode(QIODevice::NotOpen);    setReadBufferSize(readBufferSize);    setRightsBufferSize(rightsBufferSize);}/*!  Destroys the QUnixSocket instance.  Any unsent data is discarded.  */QUnixSocket::~QUnixSocket(){    abort();    delete d;}/*!  Attempt to connect to \a path.  This method is synchronous and will return true if the connection succeeds and  false otherwise.  In the case of failure, \l QUnixSocket::error() will be set  accordingly.  Any existing connection will be aborted, and all pending data will be  discarded.  \sa QUnixSocket::close() QUnixSocket::abort() QUnixSocket::error()  */bool QUnixSocket::connect(const QByteArray & path){    int _true;    int crv;#ifdef QUNIXSOCKET_DEBUG    qDebug() << "QUnixSocket: Connect requested to '"             << path << "'";#endif    abort(); // Reset any existing connection    if(UnconnectedState != d->state) // abort() caused a signal and someone messed                                 // with us.  We'll assume they know what                                 // they're doing and bail.  Alternative is to                                 // have a special "Connecting" state        return false;    if(path.isEmpty() || path.size() > UNIX_PATH_MAX) {        d->error = InvalidPath;        return false;    }    // Create the socket    d->fd = ::socket(PF_UNIX, SOCK_STREAM, 0);    if(-1 == d->fd) {#ifdef QUNIXSOCKET_DEBUG        qDebug() << "QUnixSocket: Unable to create socket ("                 << strerror(errno) << ")";#endif        d->error = ResourceError;        goto connect_error;    }    // Set socket options    _true = 1;    crv = ::setsockopt(d->fd, SOL_SOCKET, SO_PASSCRED, (void *)&_true,                       sizeof(int));    if(-1 == crv) {#ifdef QUNIXSOCKET_DEBUG        qDebug() << "QUnixSocket: Unable to configure socket ("                 << ::strerror(errno) << ")";#endif        d->error = ResourceError;        goto connect_error;    }    // Construct our unix address    struct ::sockaddr_un addr;    addr.sun_family = AF_UNIX;    ::memcpy(addr.sun_path, path.data(), path.size());    if(path.size() < UNIX_PATH_MAX)        addr.sun_path[path.size()] = '\0';    // Attempt the connect    crv = ::connect(d->fd, (sockaddr *)&addr, sizeof(sockaddr_un));    if(-1 == crv) {#ifdef QUNIXSOCKET_DEBUG        qDebug() << "QUnixSocket: Unable to connect ("                 << ::strerror(errno) << ")";#endif        if(ECONNREFUSED == errno)            d->error = ConnectionRefused;        else if(ENOENT == errno)            d->error = NonexistentPath;        else            d->error = UnknownError;        goto connect_error;    }    // We're connected!    d->address = path;    d->state = ConnectedState;    d->readNotifier = new QSocketNotifier(d->fd, QSocketNotifier::Read, d);    d->writeNotifier = new QSocketNotifier(d->fd, QSocketNotifier::Write, d);    QObject::connect(d->readNotifier, SIGNAL(activated(int)),                     d, SLOT(readActivated()));    QObject::connect(d->writeNotifier, SIGNAL(activated(int)),                     d, SLOT(writeActivated()));    d->readNotifier->setEnabled(true);    d->writeNotifier->setEnabled(false);    setOpenMode(QIODevice::ReadWrite);    emit stateChanged(ConnectedState);#ifdef QUNIXSOCKET_DEBUG    qDebug() << "QUnixSocket: Connected to " << path;#endif    return true;connect_error: // Cleanup failed connection    if(-1 != d->fd) {#ifdef QUNIXSOCKET_DEBUG        int closerv =#endif            ::close(d->fd);#ifdef QUNIXSOCKET_DEBUG        if(0 != closerv) {            qDebug() << "QUnixSocket: Unable to close file descriptor after "                        "failed connect (" << ::strerror(errno) << ")";        }#endif    }    d->fd = -1;    return false;}/*!  Sets the socket descriptor to use to \a socketDescriptor, bypassing  QUnixSocket's connection infrastructure, and return true on success and false  on failure.  \a socketDescriptor must be in the connected state, and must be  a Unix domain socket descriptor.  Following a successful call to this method,  the QUnixSocket instance will be in the Connected state and will have assumed  ownership of \a socketDescriptor.  Any existing connection will be aborted, and all pending data will be  discarded.  \sa QUnixSocket::connect()*/bool QUnixSocket::setSocketDescriptor(int socketDescriptor){    abort();    if(UnconnectedState != state()) // See QUnixSocket::connect()        return false;    // Attempt to set the socket options    if(-1 == socketDescriptor) {#ifdef QUNIXSOCKET_DEBUG        qDebug() << "QUnixSocket: User provided socket is invalid";#endif        d->error = ResourceError;        return false;    }    // Set socket options    int _true = 1;    int crv = ::setsockopt(socketDescriptor, SOL_SOCKET,                           SO_PASSCRED, (void *)&_true, sizeof(int));    if(-1 == crv) {#ifdef QUNIXSOCKET_DEBUG        qDebug() << "QUnixSocket: Unable to configure client provided socket ("                 << ::strerror(errno) << ")";#endif        d->error = ResourceError;        return false;    }    d->fd = socketDescriptor;    d->state = ConnectedState;    d->address = QByteArray();    setOpenMode(QIODevice::ReadWrite);    d->readNotifier = new QSocketNotifier(d->fd, QSocketNotifier::Read, d);    d->writeNotifier = new QSocketNotifier(d->fd, QSocketNotifier::Write, d);    QObject::connect(d->readNotifier, SIGNAL(activated(int)),                     d, SLOT(readActivated()));    QObject::connect(d->writeNotifier, SIGNAL(activated(int)),                     d, SLOT(writeActivated()));    d->readNotifier->setEnabled(true);    d->writeNotifier->setEnabled(false);    emit stateChanged(d->state);    return true;}/*!  Returns the socket descriptor currently in use.  This method will return -1  if the QUnixSocket instance is in the UnconnectedState \l {QUnixSocket::state()}{state. }  \sa QUnixSocket::setSocketDescriptor()  */int QUnixSocket::socketDescriptor() const{    return d->fd;}/*!  Abort the connection.  This will immediately disconnect (if connected) and  discard any pending data.  Following a call to QUnixSocket::abort() the  object will always be in the disconnected \link QUnixSocket::state() state.  \endlink  \sa QUnixSocket::close()*/void QUnixSocket::abort(){    setOpenMode(QIODevice::NotOpen);    // We want to be able to use QUnixSocket::abort() to cleanup our state but    // also preserve the error message that caused the abort.  It is not    // possible to reorder code to do this:    //        abort();    //        d->error = SomeError    // as QUnixSocket::abort() might emit a signal and we need the error to be    // set within that signal.  So, if we want an error message to be preserved    // across a *single* call to abort(), we set the    // QUnixSocketPrivate::CausedAbort flag in the error.    if(d->error & QUnixSocketPrivate::CausedAbort)        d->error = (QUnixSocket::SocketError)(d->error &                                              ~QUnixSocketPrivate::CausedAbort);    else        d->error = NoError;    if( UnconnectedState == d->state) return;#ifdef QUNIXSOCKET_DEBUG    int closerv =#endif        ::close(d->fd);#ifdef QUNIXSOCKET_DEBUG    if(0 != closerv) {        qDebug() << "QUnixSocket: Unable to close socket during abort ("                 << strerror(errno) << ")";    }#endif    // Reset variables    d->fd = -1;    d->state = UnconnectedState;    d->dataBufferLength = 0;    d->flushAncillary();    d->address = QByteArray();    if(d->readNotifier) {        d->readNotifier->setEnabled(false);        delete d->readNotifier;    }    if(d->writeNotifier) {        d->writeNotifier->setEnabled(false);        delete d->writeNotifier;    }    d->readNotifier = 0;    d->writeNotifier = 0;    d->writeQueue.clear();    d->writeQueueBytes = 0;    if(d->closingTimer) {        d->killTimer(d->closingTimer);    }    d->closingTimer = 0;    emit stateChanged(d->state);}/*!  Close the connection.  The instance will enter the Closing  \l {QUnixSocket::state()}{state } until all pending data has been  transmitted, at which point it will enter the Unconnected state.  Even if there is no pending data for transmission, the object will never  jump directly to Disconnect without first passing through the  Closing state.  \sa QUnixSocket::abort()  */void QUnixSocket::close(){    if(ConnectedState != state()) return;    d->state = ClosingState;    if(d->writeQueue.isEmpty()) {        d->closingTimer = d->startTimer(0); // Start a timer to "fake"                                            // completing writes    }    emit stateChanged(d->state);}/*!  Writes all unsent data to the socket, and blocks until transmission has  completed.  \b {Warning:} Calling this function from your main (GUI) thread may cause  your user interface to freeze.  */void QUnixSocket::flush(){    while(!d->writeQueue.isEmpty())        d->writeActivated();}/*!  Returns the last error to have occurred on this object.  This method is not  destructive, so multiple calls to QUnixSocket::error() will return the same  value.  The error is only reset by a call to \l QUnixSocket::connect() or  \l QUnixSocket::abort()  */QUnixSocket::SocketError QUnixSocket::error() const{    return (QUnixSocket::SocketError)        (d->error & ~QUnixSocketPrivate::CausedAbort);}/*!  Returns the connection state of this instance.  */QUnixSocket::SocketState QUnixSocket::state() const{    return d->state;}/*!  Returns the Unix path address passed to \l QUnixSocket::connect().  This  method will return an empty path if the object is in the Unconnected  \l {QUnixSocket::state()}{state } or was connected through a call  to \l QUnixSocket::setSocketDescriptor()  \sa QUnixSocket::connect() QUnixSocket::setSocketDescriptor()  */QByteArray QUnixSocket::address() const{    return d->address;}/*!  Returns the number of bytes available for immediate retrieval through a call  to \l QUnixSocket::read().  */qint64 QUnixSocket::bytesAvailable() const{    return QIODevice::bytesAvailable() + d->dataBufferLength;}/*!  Returns the number of enqueued bytes still to be written to the socket.  */qint64 QUnixSocket::bytesToWrite() const{    return d->writeQueueBytes;}/*!  Returns the size of the read buffer in bytes.  The read buffer size  determines the amount of byte data that can be read from the socket in one go.  The read buffer size caps the maximum value that can be returned by  \l QUnixSocket::bytesAvailable() and will always be greater than zero.  By  default, the read buffer size is 1024 bytes.  The size of the read buffer is independent of the rights buffer, which can be  queried by \l QUnixSocket::rightsBufferSize().  \sa QUnixSocket::setReadBufferSize()  */qint64 QUnixSocket::readBufferSize() const{    return d->dataBufferCapacity;}/*!  Sets the \a size of the socket's read buffer in bytes.  The size of the read buffer is independent of the rights buffer, which can be  set by \l QUnixSocket::setRightsBufferSize().  Attempting to reduce the buffer size while bytes are available for reading  (ie. while the buffer is in use) will fail.  \sa QUnixSocket::readBufferSize()  */void QUnixSocket::setReadBufferSize(qint64 size){    Q_ASSERT(size > 0);    if(size == d->dataBufferCapacity || d->dataBufferLength) return;    if(d->dataBuffer) delete [] d->dataBuffer;    d->dataBuffer = new char[size];    d->dataBufferCapacity = size;}/*!  Returns the size of the rights buffer in rights entries.  The rights buffer  size determines the number of rights transferences that can be received in  any message.  Unlike byte stream data which can be fragmented into many  smaller messages if the \link QUnixSocket::readBufferSize() read buffer  \endlink is not large enough to contain all the available data, rights data  is transmitted as unfragmentable datagrams.  If the rights buffer is not  large enough to contain this unfragmentable datagram, the datagram will be  truncated and rights data irretrievably lost.  If truncation occurs, the  \l QUnixSocketMessage::rightsWereTruncated() flag will be set.  By default  the rights buffer size is 0 entries - rights data cannot be received.  The size of the rights buffer is independent of the read buffer, which can be  queried by \l QUnixSocket::readBufferSize().  \sa QUnixSocket::setRightsBufferSize()  */qint64 QUnixSocket::rightsBufferSize() const{    return d->ancillaryBufferCount;}/*!  Sets the \a size of the socket's rights buffer in rights entries.  The size of the rights buffer is independent of the read buffer, which can be  set by \l QUnixSocket::setReadBufferSize().  Attempting to reduce the buffer size while bytes are available for reading  (ie. while the buffer is in use) will fail.

⌨️ 快捷键说明

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