开发的最初意图很简单,就是方便从台式传输小电影到笔记本上(狗头狗头)
其实就是懒得下载第三方软件了,然后看着百度网盘发呆半个小时后,就打算搞一个出来自己用。
后来用习惯了发现局域网环境下多方共享文件YYDS,速度基本上跑满带宽,杠杠滴。
如果自己有固定IP的外网存储,也可以直接拿来当点对点传输使用。
直接上效果吧
整体看功能是比较简单的,上传、下载、删除、搜索等。还可以检测服务端的容量情况
为了能同时上传和下载更多小电影,我建了个线程池,开启了多线程上传下载,示例代码如下:
QThread * CTcpMultiThreadPool::getFreeThread()
{
QThread *pthread = NULL;
auto begin = haAllThread.begin();
for (begin; begin != haAllThread.end(); ++begin)
{
if (begin.value() < MAX_VALUE)
{
m_CurThread = begin;
m_CurThread.value()++;
pthread = m_CurThread.key();
break;
}
}
return pthread;
}
传输使用了自定义的协议,先传输文件信息,再传输文件的二进制数据
void FileHandleThread::getStartTransferSlot()
{
if (!init())
{
emit sendConnentStateFailSignal(false);
closeConnect();
return;
}
if (m_type == 1)
{
QFile file(m_FileInfo.FilePath);
file.open(QIODevice::ReadOnly);
m_FileBuf.resize(SEND_BLOCK_SIZE + 128);
QByteArray head = getHead(m_FileInfo, 1) + "###";
m_FileBuf = head + file.read(SEND_BLOCK_SIZE);
m_SendSize = m_Socket->write(m_FileBuf);
m_Socket->waitForBytesWritten(3000);
m_SendSize = m_SendSize - head.size();
qint64 fileSize = m_FileInfo.FileSize.toLongLong();
emit sendProcessPercentSignal(m_SendSize);
if (m_SendSize < fileSize)
{
do
{
if (DenyFlag)
{
m_SaveFile.close();
closeConnect();
return;
}
while (StopTransferFlag)
{
if (DenyFlag)
{
m_SaveFile.close();
closeConnect();
return;
}
}
m_FileBuf = file.read(SEND_BLOCK_SIZE);
m_SendSize += m_Socket->write(m_FileBuf);
m_Socket->waitForBytesWritten(3000);
emit sendProcessPercentSignal(m_SendSize);
} while (m_SendSize < fileSize);
}
emit sendFinishSignal();
closeConnect();
}
else if (m_type == 2)
{
QByteArray head = getHead(m_FileInfo, 2) + "###";
int size = m_Socket->write(head);
m_Socket->waitForBytesWritten(3000);
m_ReceiveLen = 0;
}
}
还加入了中途取消上传和下载的功能
void TransfersInfo::getDenyTransferSlot(const QString & md5, int type)
{
QMutexLocker locker(&gTasksMutex);
ControlWidget *wg = nullptr;
QListWidgetItem *item = nullptr;
if (type == 1)
{
for (int i = 0; i < m_UploadListWidget->count(); i++)
{
if (m_UploadListWidget->item(i)->whatsThis().compare(md5) == 0)
{
item = m_UploadListWidget->item(i);
m_UploadListWidget->takeItem(i);
delete item;
break;
}
}
disconnect(m_UploadListMapControlWidget[md5], &ControlWidget::sendTransferFinishSignal, this, &TransfersInfo::getTransferFinishSlot);
disconnect(m_UploadListMapControlWidget[md5], &ControlWidget::sendDenyTransferInfoSignal, this, &TransfersInfo::getDenyTransferSlot);
wg = m_UploadListMapControlWidget[md5];
m_UploadListMapControlWidget.erase(md5);
m_UploadMap.erase(md5);
if (wg)
{
delete wg;
}
}
else if (type == 2)
{
for (int i = 0; i < m_DownLoadListWidget->count(); i++)
{
if (m_DownLoadListWidget->item(i)->whatsThis().compare(md5) == 0)
{
item = m_DownLoadListWidget->item(i);
m_DownLoadListWidget->takeItem(i);
delete item;
break;
}
}
disconnect(m_DownloadListMapControlWidget[md5], &ControlWidget::sendTransferFinishSignal, this, &TransfersInfo::getTransferFinishSlot);
disconnect(m_DownloadListMapControlWidget[md5], &ControlWidget::sendDenyTransferInfoSignal, this, &TransfersInfo::getDenyTransferSlot);
wg = m_DownloadListMapControlWidget[md5];
m_DownloadListMapControlWidget.erase(md5);
m_DownloadMap.erase(md5);
if (wg)
{
delete wg;
}
}
}
大致就那么多吧,很久之前写的了,回忆一下