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

📄 peerwireclient.cpp

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
{    char buffer[1024];    qint64 totalRead = 0;    do {        qint64 bytesRead = QTcpSocket::readData(buffer, qMin<qint64>(sizeof(buffer), bytes - totalRead));        if (bytesRead <= 0)            break;        qint64 oldSize = incomingBuffer.size();        incomingBuffer.resize(oldSize + bytesRead);        memcpy(incomingBuffer.data() + oldSize, buffer, bytesRead);        totalRead += bytesRead;    } while (totalRead < bytes);    if (totalRead > 0) {        downloadSpeedData[0] += totalRead;        emit bytesReceived(totalRead);        processIncomingData();    }    return totalRead;}// Returns the average number of bytes per second this client is// downloading.qint64 PeerWireClient::downloadSpeed() const{    qint64 sum = 0;    for (unsigned int i = 0; i < sizeof(downloadSpeedData) / sizeof(qint64); ++i)        sum += downloadSpeedData[i];    return sum / (8 * 2);}// Returns the average number of bytes per second this client is// uploading.qint64 PeerWireClient::uploadSpeed() const{    qint64 sum = 0;    for (unsigned int i = 0; i < sizeof(uploadSpeedData) / sizeof(qint64); ++i)        sum += uploadSpeedData[i];    return sum / (8 * 2);}bool PeerWireClient::canTransferMore() const{    return !incomingBuffer.isEmpty() || QTcpSocket::bytesAvailable() > 0        || !outgoingBuffer.isEmpty() || !pendingBlocks.isEmpty();}void PeerWireClient::timerEvent(QTimerEvent *event){    if (event->timerId() == transferSpeedTimer) {        // Rotate the upload / download records.        for (int i = 6; i >= 0; --i) {            uploadSpeedData[i + 1] = uploadSpeedData[i];            downloadSpeedData[i + 1] = downloadSpeedData[i];        }        uploadSpeedData[0] = 0;        downloadSpeedData[0] = 0;    } else if (event->timerId() == timeoutTimer) {        // Disconnect if we timed out; otherwise the timeout is        // restarted.        if (invalidateTimeout) {            invalidateTimeout = false;        } else {            abort();        }    } else if (event->timerId() == pendingRequestTimer) {        abort();    } else if (event->timerId() == keepAliveTimer) {        sendKeepAlive();    }    QTcpSocket::timerEvent(event);}// Sends the handshake to the peer.void PeerWireClient::sendHandShake(){    sentHandShake = true;    // Restart the timeout    if (timeoutTimer)        killTimer(timeoutTimer);    timeoutTimer = startTimer(ClientTimeout);    // Write the 68 byte PeerWire handshake.    write(&ProtocolIdSize, 1);    write(ProtocolId, ProtocolIdSize);    write(QByteArray(8, '\0'));    write(infoHash);    write(peerIdString);}void PeerWireClient::processIncomingData(){    invalidateTimeout = true;    if (!receivedHandShake) {        // Check that we received enough data        if (incomingBuffer.size() < MinimalHeaderSize)            return;        // Sanity check the protocol ID        QByteArray id = read(ProtocolIdSize + 1);        if (id.at(0) != ProtocolIdSize || !id.mid(1).startsWith(ProtocolId)) {            abort();            return;        }        // Discard 8 reserved bytes, then read the info hash and peer ID        (void) read(8);        // Read infoHash        QByteArray peerInfoHash = read(20);        if (!infoHash.isEmpty() && peerInfoHash != infoHash) {            abort();            return;        }        emit infoHashReceived(peerInfoHash);        if (infoHash.isEmpty()) {            abort();            return;        }        // Send handshake        if (!sentHandShake)            sendHandShake();        receivedHandShake = true;    }    // Handle delayed peer id arrival    if (!gotPeerId) {        if (incomingBuffer.size() < 20)            return;        gotPeerId = true;        if (read(20) == peerIdString) {            // We connected to ourself            abort();            return;        }    }    // Initialize keep-alive timer    if (!keepAliveTimer)        keepAliveTimer = startTimer(KeepAliveInterval);    do {        // Find the packet length        if (nextPacketLength == -1) {            if (incomingBuffer.size() < 4)                return;            char tmp[4];            read(tmp, sizeof(tmp));            nextPacketLength = fromNetworkData(tmp);            if (nextPacketLength < 0 || nextPacketLength > 200000) {                // Prevent DoS                abort();                return;            }        }        // KeepAlive        if (nextPacketLength == 0) {            nextPacketLength = -1;            continue;        }        // Wait with parsing until the whole packet has been received        if (incomingBuffer.size() < nextPacketLength)            return;        // Read the packet        QByteArray packet = read(nextPacketLength);        if (packet.size() != nextPacketLength) {            abort();            return;        }        switch (packet.at(0)) {        case ChokePacket:            // We have been choked.            pwState |= ChokedByPeer;            incoming.clear();            if (pendingRequestTimer)                killTimer(pendingRequestTimer);            emit choked();            break;        case UnchokePacket:            // We have been unchoked.            pwState &= ~ChokedByPeer;            emit unchoked();            break;        case InterestedPacket:            // The peer is interested in downloading.            pwState |= PeerIsInterested;            emit interested();            break;        case NotInterestedPacket:            // The peer is not interested in downloading.            pwState &= ~PeerIsInterested;            emit notInterested();            break;        case HavePacket: {            // The peer has a new piece available.            quint32 index = fromNetworkData(&packet.data()[1]);            if (index < quint32(peerPieces.size())) {                // Only accept indexes within the valid range.                peerPieces.setBit(int(index));            }            emit piecesAvailable(availablePieces());            break;        }        case BitFieldPacket:            // The peer has the following pieces available.            for (int i = 1; i < packet.size(); ++i) {                for (int bit = 0; bit < 8; ++bit) {                    if (packet.at(i) & (1 << (7 - bit))) {                        int bitIndex = int(((i - 1) * 8) + bit);                        if (bitIndex >= 0 && bitIndex < peerPieces.size()) {                            // Occasionally, broken clients claim to have                            // pieces whose index is outside the valid range.                            // The most common mistake is the index == size                            // case.                            peerPieces.setBit(bitIndex);                        }                    }                }            }            emit piecesAvailable(availablePieces());            break;        case RequestPacket: {            // The peer requests a block.            quint32 index = fromNetworkData(&packet.data()[1]);            quint32 begin = fromNetworkData(&packet.data()[5]);            quint32 length = fromNetworkData(&packet.data()[9]);            emit blockRequested(int(index), int(begin), int(length));            break;        }        case PiecePacket: {            int index = int(fromNetworkData(&packet.data()[1]));            int begin = int(fromNetworkData(&packet.data()[5]));                       incoming.removeAll(TorrentBlock(index, begin, packet.size() - 9));            // The peer sends a block.            emit blockReceived(index, begin, packet.mid(9));            // Kill the pending block timer.            if (pendingRequestTimer) {                killTimer(pendingRequestTimer);                pendingRequestTimer = 0;            }            break;        }        case CancelPacket: {            // The peer cancels a block request.            quint32 index = fromNetworkData(&packet.data()[1]);            quint32 begin = fromNetworkData(&packet.data()[5]);            quint32 length = fromNetworkData(&packet.data()[9]);            for (int i = 0; i < pendingBlocks.size(); ++i) {                const BlockInfo &blockInfo = pendingBlocks.at(i);                if (blockInfo.pieceIndex == int(index)                    && blockInfo.offset == int(begin)                    && blockInfo.length == int(length)) {                    pendingBlocks.removeAt(i);                    break;                }            }            break;        }        default:            // Unsupported packet type; just ignore it.            break;        }        nextPacketLength = -1;    } while (incomingBuffer.size() > 0);}qint64 PeerWireClient::readData(char *data, qint64 size){    int n = qMin<int>(size, incomingBuffer.size());    memcpy(data, incomingBuffer.constData(), n);    incomingBuffer.remove(0, n);    return n;}qint64 PeerWireClient::readLineData(char *data, qint64 maxlen){    return QIODevice::readLineData(data, maxlen);}qint64 PeerWireClient::writeData(const char *data, qint64 size){    int oldSize = outgoingBuffer.size();    outgoingBuffer.resize(oldSize + size);    memcpy(outgoingBuffer.data() + oldSize, data, size);    emit readyToTransfer();    return size;}

⌨️ 快捷键说明

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