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

📄 downloader.cpp

📁 多线程下载工具,程序源码,对想开发类似快车或蚂蚁的朋友有用!
💻 CPP
字号:
/* * nzb * * Copyright (C) 2004-2006 Mattias Nordstrom <matta at ftlight net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA * * * Authors: *   Mattias Nordstrom <matta at ftlight net> * * $Id: downloader.cpp,v 1.7 2006/05/14 10:37:53 mnordstr Exp $ *   This file provides the NNTP downloader. */#include "downloader.h"#include "mainwindow.h"Downloader::Downloader(NzbList *nzblist, int thread_id, QMutex *file_lock, QTableWidget *l, QObject *parent){	this->nzblist = nzblist;	this->parent = parent;	this->thread_id = thread_id;	this->file_lock = file_lock;	this->l = l;	this->use_ssl = false;	connect(this, SIGNAL(downloadEvent(QString, int, int)), parent, SLOT(downloadEvent(QString, int, int)));}void Downloader::run(){	qDebug("Downloader running.");		QTimer::singleShot(0, this, SLOT(init()));	this->exec();		qDebug("Downloader done.");}void Downloader::init(){	file = 0, seg = 0;	downloading = false;	connect(this, SIGNAL(processNext()), this, SLOT(processFiles()));		use_ssl = ((MainWindow*)parent)->getConfig()->value("server/ssl").toBool();		emit downloadEvent("Connecting", thread_id);	((MainWindow*)parent)->getDownloaderItem(thread_id)->setIcon(QIcon(":/images/connect_creating.png"));	usenet = new QTcpSocket();	connect(usenet, SIGNAL(connected()), this, SLOT(gotConnected()));		if (use_ssl) {		connect(&ssl, SIGNAL(readyRead()), this, SLOT(gotData()));		connect(usenet, SIGNAL(readyRead()), this, SLOT(ssl_readyRead()));		connect(&ssl, SIGNAL(outgoingSSLDataReady()), this, SLOT(ssl_outgoingReady()));	} else {		connect(usenet, SIGNAL(readyRead()), this, SLOT(gotData()));	}		initialize(((MainWindow*)parent)->getConfig()->value("server/host").toString(), ((MainWindow*)parent)->getConfig()->value("server/port").toInt());		last_time = QTime::currentTime();	last_bytes = 0;	total_bytes = 0;		QTimer *speedTimer = new QTimer(this);	connect(speedTimer, SIGNAL(timeout()), this, SLOT(speedMonitor()));	speedTimer->start(5000);}void Downloader::processFiles(){	if (downloading) return;		if (getNext()) {			downloading = true;			emit downloadEvent("Downloading ["+QString::number(file+1)+": "+QString::number(seg+1)+"/"+QString::number(nzblist->getFile(file)->getSegments()->size())+"] "+nzblist->getFile(file)->getSegment(seg)->getMsgid(), thread_id);			getArticle(nzblist->getFile(file)->getSegment(seg)->getMsgid());	}}bool Downloader::getNext(){	file_lock->lock();		for (;;) {		if (nzblist->getFile(file)->getSegment(seg)->getStatus() == NZB_NONE && l->item(file, 0)->checkState() == Qt::Checked) {			nzblist->getFile(file)->getSegment(seg)->setStatus(NZB_DOWNLOADING);			file_lock->unlock();			return true;		}				if (nzblist->getFile(file)->getSegment(seg)->getStatus() == NZB_NONE && l->item(file, 0)->checkState() == Qt::Unchecked) {			nzblist->getFile(file)->getSegment(seg)->setStatus(NZB_DL_SKIPPED);			file_lock->unlock();			emit downloadEvent("", file, 2);			emit processNext();						return false;		}				if (nzblist->getFile(file)->getSegments()->size() == seg+1) {			if (nzblist->getList()->size() == file+1) {				file_lock->unlock();								emit downloadEvent("Disconnecting", thread_id);				terminate();				emit downloadEvent("Disconnected", thread_id);								return false;			}						file = file + 1;			seg = 0;		} else {			seg = seg + 1;		}	}		return false;}void Downloader::stop(){	emit downloadEvent("Disconnecting", thread_id);	terminate();	emit downloadEvent("Disconnected", thread_id);	dldata.clear();	delete usenet;	this->exit();}void Downloader::initialize(QString host, int port){	usenet->connectToHost(host, port);}void Downloader::gotConnected(){	if (use_ssl) {		if (!ssl.begin()) {			((MainWindow*)parent)->getDownloaderItem(thread_id)->setIcon(QIcon(":/images/connect_no.png"));			usenet->close();			emit downloadEvent("SSL connection failed", thread_id);			dldata.clear();		} else {			((MainWindow*)parent)->getDownloaderItem(thread_id)->setIcon(QIcon(":/images/encrypted.png"));		}	} else {		((MainWindow*)parent)->getDownloaderItem(thread_id)->setIcon(QIcon(":/images/connect_established.png"));	}}void Downloader::terminate(){	if (use_ssl) {		ssl.send(((QString)("QUIT\r\n")).toAscii());		usenet->close();	} else {		usenet->write(((QString)("QUIT\r\n")).toAscii());		usenet->close();	}		((MainWindow*)parent)->getDownloaderItem(thread_id)->setIcon(QIcon(":/images/connect_no.png"));}void Downloader::getArticle(QString msgid){	if (use_ssl) {		ssl.send(("ARTICLE "+msgid+"\r\n").toAscii());	} else {		usenet->write(("ARTICLE "+msgid+"\r\n").toAscii());		usenet->flush();	}		dldata.clear();}void Downloader::ssl_readyRead(){	/*QByteArray buf;	int size = usenet->bytesAvailable();	buf.resize(size);	usenet->readBlock(buf.data(), size);*/	ssl.putIncomingSSLData(usenet->readAll());}void Downloader::ssl_outgoingReady(){	usenet->write(ssl.getOutgoingSSLData());}void Downloader::gotData(){	QIODevice *buffer;	QBuffer ssl_buf;	if (use_ssl) {		ssl_buf.open(QBuffer::ReadWrite);		ssl_buf.write(ssl.recv());		ssl_buf.seek(0);		buffer = &ssl_buf;	} else {		buffer = usenet;	}		if (!buffer->bytesAvailable()) {		qDebug("gotData() empty.");		return;	}	total_bytes += buffer->bytesAvailable();		QByteArray hdata;	int pos;		if (dldata.isEmpty()) {		hdata = buffer->readLine();		if (hdata.left(3) == "200" || hdata.left(3) == "201") {			if (((MainWindow*)parent)->getConfig()->value("server/auth").toBool()) {				if (use_ssl) {					ssl.send(("AUTHINFO USER "+((MainWindow*)parent)->getConfig()->value("server/username").toString()+"\r\n").toAscii());				} else {					buffer->write(("AUTHINFO USER "+((MainWindow*)parent)->getConfig()->value("server/username").toString()+"\r\n").toAscii());					((QTcpSocket*)buffer)->flush();				}				return;			} else {				emit downloadEvent("Connected", thread_id, 3);				emit processNext();				return;			}		} else if (hdata.left(3) == "381") {			if (use_ssl) {				ssl.send(("AUTHINFO PASS "+((MainWindow*)parent)->getConfig()->value("server/password").toString()+"\r\n").toAscii());			} else {				buffer->write(("AUTHINFO PASS "+((MainWindow*)parent)->getConfig()->value("server/password").toString()+"\r\n").toAscii());				((QTcpSocket*)buffer)->flush();			}			return;		} else if (hdata.left(3) == "281") {			qDebug("Connected");			emit downloadEvent("Connected", thread_id, 3);			emit processNext();			return;		} else if (hdata.left(1) == "4" || hdata.left(1) == "5") {			emit downloadEvent("NNTP Error: "+hdata, thread_id);			qDebug() << "Error: " << hdata;			return;		} else if (hdata.left(2) == "22") {			dldata = hdata;			dldata += buffer->readAll();		} else {			/*emit downloadEvent("Connect failure", thread_id);			qDebug("Connection failed.");			nzblist->getFile(file)->getSegment(seg)->setStatus(NZB_DOWNLOADED);			buffer->close();			qDebug("NNTP Protocol handshake error.");			qDebug() << "Data: " << hdata;			return;*/			dldata = hdata+buffer->readAll();		}	} else {		dldata += buffer->readAll();	}		if (dldata.right(5) == "\r\n.\r\n") {		downloading = false;		dldata = dldata.left(dldata.length() - 3);		pos = dldata.indexOf("\r\n\r\n", 0);		dldata = dldata.mid(pos + 4, dldata.length() - (pos + 4));		if (dldata.left(2) == "..") {			dldata.remove(0, 1);		}				pos = 0;		while ((pos = dldata.indexOf("\r\n..", pos+3)) != -1) {			dldata.remove(pos + 2, 1);		}				nzblist->getFile(file)->getSegment(seg)->setData(dldata);		nzblist->getFile(file)->getSegment(seg)->setStatus(NZB_DOWNLOADED);		//dldata.clear();					emit downloadEvent("", file, 2);		emit processNext();	}}void Downloader::speedMonitor(){	if (int secs = last_time.secsTo(QTime::currentTime())) {		double speed = ((total_bytes - last_bytes) / secs) / 1000;		last_time = QTime::currentTime();		last_bytes = total_bytes;			emit downloadEvent(QString::number(speed), thread_id, 4);	}}

⌨️ 快捷键说明

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