QT下用QTcpSocket传输文件, 调用了QTcpSocket::write()但是怎么没有bytesWritten信号上来
最近看Qt 的网络编程关于Tcp传输文件的问题, (按照这个文章实现的[url]http://www.yafeilinux.com/?p=806[/url]),
但是我很郁闷的是为什么我的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();
}
[解决办法]
正在学习中~
[解决办法]
我碰到过的问题是这样的:
Qt中的信号/槽响应机制, 以及定时器等这些功能都是需要通过QApplication的实例来进行消息分配, 如果没有QApplication的实例, 也就没有这些功能了.
详见 这里.
不知对你是否有帮助?