QT下用QTcpSocket传输文件, 调用了QTcpSocket::write()但是怎么没有bytesWritten信号上来

sac_meTeor 2011-09-21 04:55:03
最近看Qt 的网络编程关于Tcp传输文件的问题, (按照这个文章实现的http://www.yafeilinux.com/?p=806),
但是我很郁闷的是为什么我的tcpSender中的bytesWritten(quint64)信号没有上来, 刚开始的连接都是正常的。 望高手指点。

tcpsender.cpp

#include <qfiledialog.h>
#include "tcpsender.h"

tcpSender::tcpSender(QWidget *parent, Qt::WFlags flags)
: QMainWindow(parent, flags)
{
loadSize = 4 * 1024;
totalBytes = 0;
bytesWrittenAA = 0;
bytesToWrite = 0;
tcpClient = new QTcpSocket(this);
connect(tcpClient, SIGNAL(connected()), this, SLOT(startTransfer()));
connect(tcpClient, SIGNAL(bytesWritten(quint64)), this, SLOT(updateClientProgress(qint64)));
connect(tcpClient, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(displayError(QAbstractSocket::SocketError)));

ui.setupUi(this);
ui.sendButton->setEnabled(false);

}
tcpSender::~tcpSender()
{
}

void tcpSender::OpenFile()
{
fileName = QFileDialog::getOpenFileName(this);
if (!fileName.isEmpty())
{
ui.sendButton->setEnabled(true);
ui.clientStatusLabel->setText(tr("打开文件 %1成功!").arg(fileName));
}
}
void tcpSender::send()
{
ui.sendButton->setEnabled(false);
bytesWrittenAA = 0;
ui.clientStatusLabel->setText(tr("连接中..."));
tcpClient->connectToHost(ui.hostLineEdit->text(), ui.portLineEdit->text().toInt());
}
void tcpSender::startTransfer()
{
localFile = new QFile(fileName);
if (!localFile->open(QFile::ReadOnly))
{
qDebug() << "open file error!";
return;
}
totalBytes = localFile->size();
QDataStream sendOut(&outBlock, QIODevice::WriteOnly);
sendOut.setVersion(QDataStream::Qt_4_6);
QString currentFileName = fileName.right(fileName.size() - fileName.lastIndexOf("/") - 1);
sendOut << qint64(0) << qint64(0) << currentFileName;
totalBytes += outBlock.size();
sendOut.device()->seek(0);
sendOut << totalBytes << qint64((outBlock.size() - sizeof(qint64) * 2));
bytesToWrite = totalBytes - tcpClient->write(outBlock);
ui.clientStatusLabel->setText(tr("已连接"));
outBlock.resize(0);
}

void tcpSender::updateClientProgress(qint64 numBytes)
{
bytesWrittenAA += numBytes;
if (bytesWrittenAA > 0)
{
outBlock = localFile->read(qMin(bytesToWrite, loadSize));
bytesToWrite -= (int)tcpClient->write(outBlock);
outBlock.resize(0);
}
else
{
localFile->close();
}
ui.clientProgressBar->setMaximum(totalBytes);
ui.clientProgressBar->setValue(bytesWrittenAA);
if (bytesWrittenAA == totalBytes)
{
ui.clientStatusLabel->setText(tr("传输文件 %1成功").arg(fileName));
localFile->close();
tcpClient->close();
}
}

void tcpSender::displayError(QAbstractSocket::SocketError)
{
qDebug() << tcpClient->errorString();
tcpClient->close();
ui.clientProgressBar->reset();
ui.clientStatusLabel->setText(tr("客户端就绪"));
ui.sendButton->setEnabled(true);
}

void tcpSender::on_openButton_clicked()
{
OpenFile();
}
void tcpSender::on_sendButton_clicked()
{
send();
}


//tcpreceiver.cpp
#include "tcpreceiver.h"
tcpReceiver::tcpReceiver(QWidget *parent, Qt::WFlags flags)
: QMainWindow(parent, flags)
{
totalBytes = 0;
bytesReceived = 0;
fileNameSize = 0;
connect(&tcpServer, SIGNAL(newConnection()), this, SLOT(acceptConnection()));

ui.setupUi(this);
}
tcpReceiver::~tcpReceiver()
{
}

void tcpReceiver::start()
{
ui.startButton->setEnabled(false);
bytesReceived = 0;
if (!tcpServer.listen(QHostAddress("192.168.0.15")/*QHostAddress::LocalHost*/, 6666))
{
qDebug() << tcpServer.errorString();
tcpServer.close();
return;
}
ui.serverStatusLabel->setText(tr("监听!!!"));
}

void tcpReceiver::acceptConnection()
{
tcpServerConnect = tcpServer.nextPendingConnection();
connect(tcpServerConnect, SIGNAL(readyRead()), this, SLOT(updateServerProgress()));
connect(tcpServerConnect, SIGNAL(QAbstractSocket::SocketError), this, SLOT(displayError()));
ui.serverStatusLabel->setText(tr("接收连接"));
tcpServer.close();
}
void tcpReceiver::updateServerProgress()
{
QDataStream in(tcpServerConnect);
in.setVersion(QDataStream::Qt_4_6);
if (bytesReceived <= sizeof(qint64) * 2)
{
if ((tcpServerConnect->bytesAvailable() >= sizeof(qint64) * 2) && (fileNameSize == 0))
{
in >> totalBytes >> fileNameSize;
bytesReceived += sizeof(qint64) * 2;
}
if ((tcpServerConnect->bytesAvailable() >= fileNameSize) && (fileNameSize != 0))
{
in >> fileName;
ui.serverStatusLabel->setText(tr("接受文件 %1...").arg(fileName));
bytesReceived += fileNameSize;
localFile = new QFile(fileName);
if (!localFile->open(QFile::WriteOnly))
{
qDebug() << "open file error!";
return;
}
}
else return;
}
if (bytesReceived < totalBytes)
{
bytesReceived += tcpServerConnect->bytesAvailable();
inBlock = tcpServerConnect->readAll();
localFile->write(inBlock);
inBlock.resize(0);
}

ui.serverProgressBar->setMaximum(totalBytes);
ui.serverProgressBar->setValue(bytesReceived);
if (bytesReceived == totalBytes)
{
tcpServerConnect->close();
localFile->close();
ui.startButton->setEnabled(true);
ui.serverStatusLabel->setText(tr("接收文件 %1 成功").arg(fileName));
}
}

void tcpReceiver::displayError(QAbstractSocket::SocketError)
{
qDebug() << tcpServerConnect->errorString();
tcpServerConnect->close();
ui.serverProgressBar->reset();
ui.serverStatusLabel->setText(tr("服务器就绪"));
ui.startButton->setEnabled(true);
}
void tcpReceiver::on_startButton_clicked()
{
start();
}

...全文
901 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
zfmss 2012-06-07
  • 打赏
  • 举报
回复
connect(tcpServerConnect, SIGNAL(readyRead()), this, SLOT(updateServerProgress()));
修改为
connect(tcpServerConnect, SIGNAL(readyRead()), this, SLOT(slotStartTransfer()));
connect(tcpServerConnect, SIGNAL(byteWritten(qint 64)), this, SLOT(updateServerProgress(qint 64)));

updateServerProgress()拆分成 slotStartTransfer() 和 updateServerProgress(qint 64).
lyf_1234 2012-05-07
  • 打赏
  • 举报
回复
一样困惑
Lutx 2011-09-23
  • 打赏
  • 举报
回复
我碰到过的问题是这样的:

Qt中的信号/槽响应机制, 以及定时器等这些功能都是需要通过QApplication的实例来进行消息分配, 如果没有QApplication的实例, 也就没有这些功能了.
详见 这里.

不知对你是否有帮助?
ass150647 2011-09-22
  • 打赏
  • 举报
回复
正在学习中~

16,224

社区成员

发帖
与我相关
我的任务
社区描述
Qt 是一个跨平台应用程序框架。通过使用 Qt,您可以一次性开发应用程序和用户界面,然后将其部署到多个桌面和嵌入式操作系统,而无需重复编写源代码。
社区管理员
  • Qt
  • 亭台六七座
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧