Hey I am making simple App that send message with UDP, and send file with TCP from PC to android with QT
but the transfer always in 99% so file never received
Transfer 99%
and i trying with qt quick too with the same logic, its end up like this (fyi the file is not saved)
enter image description here
here is my code for server
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFileDialog>
#include <QMessageBox>
#include <QDataStream>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
localFile(nullptr)
{
ui->setupUi(this);
initTcpServer();
initUdpServer();
}
MainWindow::~MainWindow()
{
tcpServer->close();
if (localFile && localFile->isOpen())
localFile->close();
delete ui;
}
void MainWindow::initTcpServer()
{
tcpServer = new QTcpServer(this);
connect(tcpServer, &QTcpServer::newConnection, this, &MainWindow::acceptTcpConnection);
if (!tcpServer->listen(QHostAddress::Any, 7600)) {
QMessageBox::critical(this, "QTCP Server", "Unable to start the server.");
}
}
void MainWindow::acceptTcpConnection()
{
tcpSocket = tcpServer->nextPendingConnection();
connect(tcpSocket, &QTcpSocket::readyRead, this, &MainWindow::readTcpData);
connect(tcpSocket, &QTcpSocket::disconnected, this, [this]()
{
ui->statusCurrent->setText("Disconnected");
});
ui->statusCurrent->setText("Connected");
}
void MainWindow::readTcpData()
{
QByteArray data = tcpSocket->readAll();
// Here, add your logic to handle received data
}
void MainWindow::initUdpServer()
{
udpSocket = new QUdpSocket(this);
udpSocket->bind(QHostAddress::Any,7501, QUdpSocket::ShareAddress);
connect(udpSocket, &QUdpSocket::readyRead, this, &MainWindow::readUdpData);
}
void MainWindow::readUdpData()
{
while (udpSocket->hasPendingDatagrams()) {
QByteArray datagram;
datagram.resize(int(udpSocket->pendingDatagramSize()));
udpSocket->readDatagram(datagram.data(), datagram.size());
ui->textBrowser->append(tr("Received UDP message: %1").arg(QString::fromUtf8(datagram)));
}
}
void MainWindow::startTransferFile()
{
if (!localFile) {
localFile = new QFile(fileName);
if (!localFile->open(QFile::ReadOnly)) {
QMessageBox::critical(this, "QTCP Server", "Unable to open the file.");
return;
}
totalBytes = localFile->size();
}
QByteArray buffer;
QDataStream out(&buffer, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_5_15);
QString currentFileName = fileName.section('/', -1);
out << qint64(0) << qint64(0) << currentFileName;
totalBytes += buffer.size();
out.device()->seek(0);
out << totalBytes << qint64((buffer.size() - sizeof(qint64) * 2));
bytesToWrite = totalBytes - tcpSocket->write(buffer);
while (!localFile->atEnd()) {
buffer = localFile->read(qMin(bytesToWrite, qint64(4 * 1024)));
bytesToWrite -= tcpSocket->write(buffer);
}
localFile->close();
delete localFile;
localFile = nullptr;
}
void MainWindow::on_pushButton_clicked()
{
startTransferFile();
}
void MainWindow::on_pushButton_2_clicked()
{
fileName = QFileDialog::getOpenFileName(this);
if (!fileName.isEmpty()) {
ui->statusbar->showMessage("File selected: " + fileName.section('/', -1));
}
}
void MainWindow::on_pushButton_3_clicked()
{
QString message = ui->lineEdit->text();
QByteArray datagram = message.toUtf8();
QHostAddress a;
QHostAddress b;
QHostAddress c;
a.setAddress("192.168.1.10");
b.setAddress("192.168.11.10");
c.setAddress("192.168.8.118");
udpSocket->writeDatagram(datagram, c, 7500);
ui->textBrowser->append("Sent: " + message);
}
for UDP i just Brute it with pair to pair the IP, I try to broadcast it but android never received so i do that
this is code for client
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
#include <QDir>
#include <QPixmap>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
tcpClient(new QTcpSocket(this)),
udpReader(new QUdpSocket(this)),
totalBytes(0),
bytesReceived(0),
fileTransferInProgress(false),
localFile(nullptr)
{
ui->setupUi(this);
udpReader->bind(QHostAddress::Any, 7500, QUdpSocket::ShareAddress);
connect(udpReader, &QUdpSocket::readyRead, this, &MainWindow::readUDPMessage);
connect(udpReader, qOverload<QAbstractSocket::SocketError>(&QUdpSocket::errorOccurred), this, &MainWindow::displayErrorUDP);
connect(tcpClient, &QTcpSocket::readyRead, this, &MainWindow::readTCPData);
connect(tcpClient, &QTcpSocket::errorOccurred, this, &MainWindow::displayError);
connectToServer();
}
MainWindow::~MainWindow()
{
delete ui;
if (localFile) {
localFile->close();
delete localFile;
}
}
void MainWindow::connectToServer()
{
//tcpClient->connectToHost("10.147.17.205", 8081);
//tcpClient->connectToHost("192.168.11.104", 7600);//WIFI REKA
tcpClient->connectToHost("192.168.1.10", 7600);//Ucup
}
void MainWindow::readUDPMessage()
{
while (udpReader->hasPendingDatagrams()) {
QByteArray datagram;
datagram.resize(int(udpReader->pendingDatagramSize()));
udpReader->readDatagram(datagram.data(), datagram.size());
ui->textBrowser->append(tr("Received UDP message: %1").arg(QString::fromUtf8(datagram)));
QPixmap pic("file:///storage/emulated/0/DCIM/Camera/IMG" + QString::fromUtf8(datagram));// HP
//QPixmap pic("storage/emulated/0/Download/" + QString::fromUtf8(datagram));// AVD
// Menyesuaikan skala gambar
QPixmap scaledPic = pic.scaled(ui->image->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
ui->image->setPixmap(scaledPic);
}
}
void MainWindow::readTCPData()
{
if (!buffer.size()) // Pastikan buffer sudah diinisialisasi dengan ukuran yang tepat
buffer.resize(bufferSize);
QDataStream sendIn(tcpClient);
sendIn.setVersion(QDataStream::Qt_5_0);
// Penerimaan header hanya dilakukan sekali
if (bytesReceived < sizeof(qint64) * 2) {
if (tcpClient->bytesAvailable() >= sizeof(qint64) * 2) {
sendIn >> totalBytes >> fileNameSize;
bytesReceived += sizeof(qint64) * 2;
}
}
// Penerimaan nama file hanya dilakukan sekali
if (fileNameSize > 0 && fileName.isEmpty() && tcpClient->bytesAvailable() >= fileNameSize) {
sendIn >> fileName;
// Construct the new file path
QString filePath = "file:///storage/emulated/0/DCIM/Camera/IMG" + fileName; //HP
//QString filePath = "storage/emulated/0/Download/" + fileName; //AVD
localFile = new QFile(filePath);
if (!localFile->open(QFile::WriteOnly)) {
qDebug() << "Cannot open file for writing";
return;
}
ui->label->setText(tr(u8"Received %1 ...").arg(fileName));
bytesReceived += fileNameSize;
fileNameSize = 0;
}
// Membaca data yang tersisa dan menulis ke file
while (tcpClient->bytesAvailable() > 0 && bytesReceived < totalBytes) {
qint64 bytesToRead = qMin(tcpClient->bytesAvailable(), (qint64)buffer.size());
qint64 bytesRead = tcpClient->read(buffer.data(), bytesToRead);
if (bytesRead > 0) {
localFile->write(buffer.data(), bytesRead);
bytesReceived += bytesRead;
}
}
// Update progress bar
ui->progressBar->setMaximum(totalBytes);
ui->progressBar->setValue(bytesReceived);
// Selesaikan transfer file
if (bytesReceived == totalBytes) {
localFile->close();
ui->label->setText(tr(u8"Successfully received file %1").arg(fileName));
delete localFile; // Penting untuk menghapus pointer
localFile = nullptr;
totalBytes = 0;
bytesReceived = 0;
fileName.clear();
}
}
void MainWindow::displayError(QAbstractSocket::SocketError socketError)
{
QMessageBox::critical(this, "Network error", tcpClient->errorString());
tcpClient->disconnect();
}
void MainWindow::displayErrorUDP (QAbstractSocket::SocketError)
{
QMessageBox::critical(this, "UDP Network Error", udpReader->errorString());
qDebug() << "UDP Error occurred:" << udpReader->errorString();
}
void MainWindow::on_pushButton_clicked()
{
QString message = ui->lineEdit->text();
QByteArray datagram = message.toUtf8();
udpReader->writeDatagram(datagram, QHostAddress::Broadcast, 7501);
ui->textBrowser->append("Sent: " + message);
}
Is there something different and need to make a note of how android take a file or TCP data ?
i already make a permission like this
permission
How to make file transfer 100% and got received in the phone