The approximate steps are as follows:
1, the server-side settings monitoring socket, start monitoring;
2, the client begins to transfer the file when the connection is successful, there is a connected () Signal connection send () slot, send () sends the header information, including the file name, the total file size and filename size, etc.;
3, the transmission of the file header information began to transfer the contents of the file, there is a byteswritten (Qint64) signal connected to the Goonsend (Qint64) slot, the former is when you want to write data sockets will start signal, that is, when you want to write data sockets, continue to transmit data, there is send () sends the header information to start triggering until the file is passed.
4, on the server side, the first to receive the file header information, and then read the filename to open a file with a new file, and then read the file name is the size of the files, to update the progress bar and continue to receive data;
5, the realization of cyclic transmission, in the client, because the first send () is triggered by the connected () signal, after each transfer should be manually call send (), on the server side, when there is new data arrives, will determine whether the header file, Therefore, each time the file is passed the bytereceived reset to 0, that is, the next time to receive data when the result of bytereceived judgment is a new file.
On the code bar, some object names and function names are not good, comments should be able to make people understand.
Client code:
Widget.h
#ifndef widget_h
#define WIDGET_H
#include <QWidget>
#include <QTcpSocket>
#include <QFile>
#include <string>
namespace Ui {
class Widget;
}
Class Widget:public Qwidget
{
q_object public
:
explicit Widget (Qwidget *parent = 0);
~widget ();
Private:
ui::widget *ui;
Qtcpsocket *tcpclient;
QFile *localfile;
QString FileName; FileName
qbytearray outblock; Qint64 Loadsize of Sub-pass
; The size of each send data
qint64 bytetowrite; The remaining data size
Qint64 totalsize; Total file size
int sendtimes; Used to mark whether to send for the first time, after the first connection signal is triggered, followed by manually calling
private slots:
void Send (); Transfer file header information
void Goonsend (Qint64); Transfer file contents
void on_openpushbutton_clicked ();
void on_sendpushbutton_clicked ();
};
#endif//Widget_h
Widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QHostAddress>
#include <QTextCodec>
#include <QFileDialog>
Widget :: Widget (QWidget * parent):
QWidget (parent),
ui (new Ui :: Widget)
{
ui-> setupUi (this);
ui-> progressLabel-> hide ();
QTextCodec :: setCodecForTr (QTextCodec :: codecForName ("GBK"));
tcpClient = new QTcpSocket (this);
sendTimes = 0;
connect (tcpClient, SIGNAL (connected ()), this, SLOT (send ())); // When the connection is successful, start to transfer files
connect (tcpClient, SIGNAL (bytesWritten (qint64)), this, SLOT (goOnSend (qint64)));
}
void Widget :: send () // Send file header information
{
byteToWrite = localFile-> size (); // The size of the remaining data
totalSize = localFile-> size ();
loadSize = 4 * 1024; // The size of data sent each time
QDataStream out (& outBlock, QIODevice :: WriteOnly);
QString currentFileName = fileName.right (fileName.size ()-fileName.lastIndexOf ('/')-1);
out << qint64 (0) << qint64 (0) << currentFileName;
totalSize + = outBlock.size (); // The total size is the file size plus the size of the file name and other information
byteToWrite + = outBlock.size ();
out.device ()-> seek (0); // Go back to the beginning of the byte stream to write a qint64 in front, which is the total size and file name and other information size
out << totalSize << qint64 (outBlock.size ());
tcpClient-> write (outBlock); // Send the read file to the socket
ui-> progressLabel-> show ();
ui-> sendProgressBar-> setMaximum (totalSize);
ui-> sendProgressBar-> setValue (totalSize-byteToWrite);
}
void Widget :: goOnSend (qint64 numBytes) // Start sending file content
{
byteToWrite-= numBytes; // Remaining data size
outBlock = localFile-> read (qMin (byteToWrite, loadSize));
tcpClient-> write (outBlock);
ui-> sendProgressBar-> setMaximum (totalSize);
ui-> sendProgressBar-> setValue (totalSize-byteToWrite);
if (byteToWrite == 0) // Send completed
ui-> sendStatusLabel-> setText (tr ("File sending completed!"));
}
Widget :: ~ Widget ()
{
delete ui;
}
void Widget :: on_openPushButton_clicked () // Open the file and get the file name (including path)
{
ui-> sendStatusLabel-> setText (tr ("Opening file ..."));
ui-> sendProgressBar-> setValue (0); // Not sent for the first time
loadSize = 0;
byteToWrite = 0;
totalSize = 0;
outBlock.clear ();
fileName = QFileDialog :: getOpenFileName (this);
localFile = new QFile (fileName);
localFile-> open (QFile :: ReadOnly);
ui-> sendStatusLabel-> setText (tr ("File% 1 opened"). arg (fileName));
}
void Widget :: on_sendPushButton_clicked ()
{
if (sendTimes == 0) // Only the first time it is sent, it happens when the connection generates the signal connect
{
tcpClient-> connectToHost (QHostAddress ("172.19.198.43"), 10000);
sendTimes = 1;
}
else
send (); // When sending for the first time, connectToHost initiates the connect signal to call send, and you need to call send after the second time
ui-> sendStatusLabel-> setText (tr ("Sending file% 1"). arg (fileName));
}
Service-Side code:
Widget.h
#ifndef widget_h
#define WIDGET_H
#include <QWidget>
#include <QtNetwork/QTcpServer>
# Include <QtNetwork/QTcpSocket>
#include <QFile>
#include <QString>
namespace Ui {
class Widget;
}
Class Widget:public Qwidget
{
q_object public
:
explicit Widget (Qwidget *parent = 0);
~widget ();
Private:
ui::widget *ui;
Qtcpserver *server;
Qtcpsocket *receivedsocket;
QFile *newfile;
Qbytearray Inblock;
QString FileName;
Qint64 totalsize; Total file size to send (file contents & filename information)
Qint64 bytereceived; The size that has been sent
private slots:
void Acceptconnection ();
void ReadClient ();
void on_pushbutton_clicked ();
};
#endif//Widget_h
Widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QTextCodec>
Widget :: Widget (QWidget * parent):
QWidget (parent),
ui (new Ui :: Widget)
{
ui-> setupUi (this);
ui-> progressLabel-> hide ();
QTextCodec :: setCodecForTr (QTextCodec :: codecForName ("GBK"));
}
void Widget :: acceptConnection ()
{
ui-> receivedStatusLabel-> setText (tr ("Connected, preparing to receive files!"));
receivedSocket = server-> nextPendingConnection ();
connect (receivedSocket, SIGNAL (readyRead ()), this, SLOT (readClient ()));
}
void Widget :: readClient ()
{
ui-> receivedStatusLabel-> setText (tr ("Receiving file ..."));
if (byteReceived == 0) // just started to receive data, this data is file information
{
ui-> receivedProgressBar-> setValue (0);
QDataStream in (receivedSocket);
in >> totalSize >> byteReceived >> fileName;
fileName = "Files /" + fileName;
newFile = new QFile (fileName);
newFile-> open (QFile :: WriteOnly);
}
else // Officially read the file content
{
inBlock = receivedSocket-> readAll ();
byteReceived + = inBlock.size ();
newFile-> write (inBlock);
newFile-> flush ();
}
ui-> progressLabel-> show ();
ui-> receivedProgressBar-> setMaximum (totalSize);
ui-> receivedProgressBar-> setValue (byteReceived);
if (byteReceived == totalSize)
{
ui-> receivedStatusLabel-> setText (tr ("% 1receive completed"). arg (fileName));
inBlock.clear ();
byteReceived = 0;
totalSize = 0;
}
}
Widget :: ~ Widget ()
{
delete ui;
}
void Widget :: on_pushButton_clicked ()
{
totalSize = 0;
byteReceived = 0;
server = new QTcpServer (this);
server-> listen (QHostAddress ("172.19.198.43"), 10000);
connect (server, SIGNAL (newConnection ()), this, SLOT (acceptConnection ()));
ui-> receivedProgressBar-> setValue (0);
ui-> receivedStatusLabel-> setText (tr ("Start listening ..."));
}
Then check the files that are received in the folder.