QT Network Programming----TCP Clients (2)

Source: Internet
Author: User
Tags error handling save file

first, the client

In the client to connect with the server, once the connection is successful, will issue a connected () signal, then the file sent.

When sending data, we first send the size information of the data. This time, we want to first send the total size of the file, then the file name length, then the file name, these three parts we are called the file header structure, and finally send the file data. So in the sending function we have to do the corresponding processing, of course, in the server's receive function we also have to do the corresponding processing. For file size, this time we used the Qint64, which is 64-bit, can represent a very large file.

1. In the previous section, we created a new project to name the project "Tcpsender". Note Add the network module.

2. We design the interface in the Widget.ui file as follows.

Here "host" after the line edit objectname for Hostlineedit, "Port" after the line edit objectname for Portlineedit; The following progress The objectname of Bar is Clientprogressbar, its Value property is set to 0, the objetname of State label is Clientstatuslabel; The objectname of the button is Openbutton; the objectname of the "Send" button is Sendbutton;

3. Make changes in the Widget.h file.

(1) Add header file #include <QtNetwork>

(2) Add private variable:

Qtcpsocket *tcpclient;

Qfile *localfile; The file to send

Qint64 totalbytes; Total data size

Qint64 Byteswritten; Data size has been sent

Qint64 Bytestowrite; Remaining data size

Qint64 loadsize; The size of the data sent each time

QString FileName; Save File path

Qbytearray Outblock; Data buffer, which holds the data to be sent every time

(3) Adding a private slot function:

Private Slots:

void Send (); Connecting to a server

void Starttransfer (); Send file size and other information

void Updateclientprogress (Qint64); Send data, update progress bar

Voiddisplayerror (Qabstractsocket::socketerror); Display Error

void OpenFile (); Open File

4. Make changes in the Widget.cpp file.

Add header file: #include <QFileDialog>

(1) Add code to the constructor:

Loadsize = 4*1024;

totalbytes = 0;

Byteswritten = 0;

Bytestowrite = 0;

TcpClient = new Qtcpsocket (this);

Connect (tcpclient,signal (connected ()), This,slot (Starttransfer ()));

When the connection server is successful, the connected () signal is sent and we begin to transfer the file

Connect (tcpclient,signal (Byteswritten (Qint64)), this,

SLOT (Updateclientprogress (Qint64)));

When data is sent successfully, we update the progress bar

Connect (tcpclient,signal error (Qabstractsocket::socketerror)), this,

SLOT (DisplayError (Qabstractsocket::socketerror)));

Ui->sendbutton->setenabled (FALSE);

Start making the Send button unavailable

We mainly carry out the initialization of variables and the correlation of several signal and slot functions.

(2) Implement open File function.

void Widget::openfile ()//Open File

{

FileName =qfiledialog::getopenfilename (this);

if (!filename.isempty ())

{

Ui->sendbutton->setenabled (TRUE);

Ui->clientstatuslabel->settext (TR ("Open file%1 succeeded.) ”)

. Arg (fileName));

}

}

The function is called in the event slot function by clicking the Open button below.

(3) Implement the connection function.

void Widget::send ()//Connect to server, perform send

{

Ui->sendbutton->setenabled (FALSE);

Byteswritten = 0;

Initialize sent bytes to 0

Ui->clientstatuslabel->settext (tr ("Connected ..."));

Tcpclient->connecttohost (Ui->hostlineedit->text (),

Ui->portlineedit->text (). ToInt ());//Connection

}

The function is called in the Click event Slot function of the Send button.

(4) Implementation of the file header structure sent.

void Widget::starttransfer ()//to deliver information such as file size

{

LocalFile = new Qfile (fileName);

if (!localfile->open (qfile::readonly))

{

Qdebug () << "Open File error!";

Return

}

TotalBytes = Localfile->size ();

Total File Size

Qdatastreamsendout (&outblock,qiodevice::writeonly);

Sendout.setversion (Qdatastream::qt_4_6);

QString currentfilename =filename.right (filename.size ()-Filename.lastindexof ('/')-1);

Sendout << qint64 (0) <<qint64 (0) << currentfilename;

Write the total size information space, file name size information space, filename

TotalBytes + + outblock.size ();

The total size here is the sum of information such as file name size and actual file size

Sendout.device ()->seek (0);

Sendout<<totalbytes<<qint64 ((outblock.size ()-sizeof (Qint64) *2));

Returns the start of the Outbolock, replacing two qint64 (0) space with actual size information

Bytestowrite = Totalbytes-tcpclient->write (Outblock);

The size of the remaining data after sending the header data

Ui->clientstatuslabel->settext (tr ("Connected"));

Outblock.resize (0);

}

(5) The following is the update progress bar, which is to send file data.

void Widget::updateclientprogress (Qint64 numbytes)//Update progress bar to implement file transfer

{

Byteswritten + = (int) numbytes;

The size of the data that has been sent

if (Bytestowrite > 0)//If data has been sent

{

Outblock =localfile->read (Qmin (bytestowrite,loadsize));

Each time you send the loadsize size data, this is set to 4KB, if the remaining data is less than 4KB,

The size of the remaining data is sent

bytestowrite-= (int) tcpclient->write (outblock);

The size of the remaining data after sending the data once

Outblock.resize (0);

Empty Send buffer

}

Else

{

Localfile->close (); If no data is sent, close the file

}

Ui->clientprogressbar->setmaximum (totalbytes);

Ui->clientprogressbar->setvalue (Byteswritten);

Update progress bar

if (Byteswritten = = totalbytes)//Send complete

{

Ui->clientstatuslabel->settext (TR ("Transfer file%1 succeeded"). Arg (fileName));

Localfile->close ();

Tcpclient->close ();

}

}

(6) Implement error handling function.

void Widget::d isplayerror (qabstractsocket::socketerror)//Display Error

{

Qdebug () <<tcpclient->errorstring ();

Tcpclient->close ();

Ui->clientprogressbar->reset ();

Ui->clientstatuslabel->settext (TR ("Client Ready"));

Ui->sendbutton->setenabled (TRUE);

}

(7) We proceed from the Widget.ui to the "open" button and the "Send" button of the Click event Slot function, and then change the following.

void widget::on_openbutton_clicked ()//Open button

{

OpenFile ();

}

void widget::on_sendbutton_clicked ()//Send button

{

Send ();

}

5. In order to make the program in Chinese does not display garbled, in the main.cpp file changes.

Add header file: #include <QTextCodec>

Add code to the main function: Qtextcodec::setcodecfortr (Qtextcodec::codecforlocale ()); Code:

Engineering documents

#-------------------------------------------------
#
# Project created by Qtcreator 2014-09-28t19:45:50
#
#-------------------------------------------------
QT       + + core GUI
QT       + + Network
GreaterThan (Qt_major_version, 4): QT + = Widgets
TARGET = Tcpsender
TEMPLATE = App
SOURCES + + main.cpp\
        Widget.cpp
HEADERS  + + widget.h
FORMS    + widget.ui

Wiget.h header File

#ifndef Widget_h
#define Widget_h
#include <QWidget>
#include <QtNetwork>
#include <QTcpServer>
#include <QTcpSocket>
#include <QFileDialog>
#include <QDebug>
#include <QMessageBox>
#include <QTextCodec>
#include <QAbstractSocket>
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;               The file to send
    Qint64 totalbytes;                      Total data size
    Qint64 Byteswritten;            The size of the data that has been sent
    Qint64 Bytestowrite;            Remaining data size
    Qint64 loadsize;            The size of the data sent each time
    QString FileName;           Save File path
    Qbytearray Outblock;            Data buffer, which holds the data to be sent every time
Private Slots:
    void Send ();        Connecting to a server
    void Starttransfer ();       Send file size and other information
    void Updateclientprogress (Qint64);          Send data, update progress bar
    void DisplayError (Qabstractsocket::socketerror socketerror);            Display Error
    void OpenFile ();                      Open File
    void on_openbutton_clicked ();
    void on_sendbutton_clicked ();
};
#endif//Widget_h

Main.cpp

#include "Widget.h"
#include <QApplication>
int main (int argc, char *argv[])
{
    Qapplication A (argc, argv);
    Widget W;
   /* Qtextcodec::setcodecforlocale (Qtextcodec::codecforname ("UTF-8"));
   qtextcodec::setcodecforcstrings (Qtextcodec::codecforname ("UTF-8"));
   QTEXTCODEC::SETCODECFORTR (Qtextcodec::codecforname ("UTF-8"));
    Qtextcodec::setcodecforlocale (Qtextcodec::codecforname ("GB18030"));
    QTEXTCODEC::SETCODECFORTR (Qtextcodec::codecforlocale ());
    W.show ();
    return A.exec ();
}

Widget.cpp file

#include "Widget.h"
#include "Ui_widget.h"
Widget::widget (Qwidget *parent):
    Qwidget (parent),
    UI (New Ui::widget)
{
    UI->SETUPUI (this);
    Loadsize = 4*1024;
    totalbytes = 0;
    Byteswritten = 0;
    Bytestowrite = 0;
    TcpClient = new Qtcpsocket (this);
    Connect (tcpclient,signal (connected ()), This,slot (Starttransfer ()));
    When the connection server is successful, the connected () signal is sent and we begin to transfer the file
    Connect (tcpclient,signal (Bytewritten (Qint64)), This,slot (Updateclientprogress (Qint64));
    When data is sent successfully, we update the progress bar
    Connect (tcpclient,signal (qabstractsocket::socketerror), This,slot (DisplayError (abstractsocket:: SocketError)));
    Ui->sendbutton->setenabled (FALSE);
    The Send button is not available at the beginning
}
Widget::~widget ()
{
    Delete UI;
}
void Widget::openfile ()
{
    FileName = Qfiledialog::getopenfilename (this);
    if (!filename.isempty ())
    {

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.