Qt學習之路_5(Qt TCP的初步使用)

Qt學習之路_5(Qt TCP的初步使用)

       在上一篇博文Qt學習之路_4(Qt UDP的初步使用) 中,初步瞭解了Qt下UDP的使用,這一節就學習下TCP的使用。2者其實流程都差不多。當然了,本文還是參考的《Qt及Qt Quick開發實戰精解》一書中的第5個例子,即局域網聊天工具中的UDP聊天和TCP文件傳送部分。另外http://www.yafeilinux.com/ 上有其源碼和相關教程下載。

         其發送端界面如下:

          

         接收端界面如下:

  

 

         發送端,也即承擔服務器角色的操作:

         在主界面程序右側選擇一個需要發送文件的用戶,彈出發送端界面後,點擊打開按鈕,在本地計算機中選擇需要發送的文件,點擊發送按鈕,則進度條上會顯示當前文件傳送的信息,有已傳送文件大小信息,傳送速度等信息。如果想關閉發送過程,則單擊關閉按鈕。

         其流程圖如下:

  

 

         接收端,也即承擔客戶端角色的操作:

         當在主界面中突然彈出一個對話框,問是否接自某個用戶名和IP地址的文件傳送信息,如果接受則單擊yes按鈕,否則就單擊no按鈕。當接收文件時,選擇好接收文件所存目錄和文件名後就開始接收文件了,其過程也會顯示已接收文件的大小,接收速度和剩餘時間的大小等信息。

         其流程圖如下:

  

 

         TCP部分程序代碼和註釋如下:

 Widget.h:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

class QUdpSocket;

class TcpServer;//可以這樣定義類?不用保護頭文件的?

namespace Ui {
class Widget;
}

// 枚舉變量標誌信息的類型,分別爲消息,新用戶加入,用戶退出,文件名,拒絕接受文件
enum MessageType{Message, NewParticipant, ParticipantLeft, FileName, Refuse};


class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

protected:
    void newParticipant(QString userName,
                        QString localHostName, QString ipAddress);
    void participantLeft(QString userName,
                         QString localHostName, QString time);
    void sendMessage(MessageType type, QString serverAddress="");

    QString getIP();
    QString getUserName();
    QString getMessage();


    void hasPendingFile(QString userName, QString serverAddress,
                        QString clientAddress, QString fileName);

private:
    Ui::Widget *ui;
    QUdpSocket *udpSocket;
    qint16 port;

    QString fileName;
    TcpServer *server;

private slots:
    void processPendingDatagrams();

    void on_sendButton_clicked();

    void getFileName(QString);
    void on_sendToolBtn_clicked();
};

#endif // WIDGET_H

 

Widget.cpp:

#include "widget.h"
#include "ui_widget.h"
#include <QUdpSocket>
#include <QHostInfo>
#include <QMessageBox>
#include <QScrollBar>
#include <QDateTime>
#include <QNetworkInterface>
#include <QProcess>

#include "tcpserver.h"
#include "tcpclient.h"
#include <QFileDialog>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    udpSocket = new QUdpSocket(this);
    port = 45454;
    udpSocket->bind(port, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint);
    connect(udpSocket, SIGNAL(readyRead()), this, SLOT(processPendingDatagrams()));
    sendMessage(NewParticipant);

    //TcpServer是tcpserver.ui對應的類,上面直接用QUdpSocket是因爲沒有單獨的udpserver.ui類
    server = new TcpServer(this);
    //sendFileName()函數一發送,則觸發槽函數getFileName()
    connect(server, SIGNAL(sendFileName(QString)), this, SLOT(getFileName(QString)));
}

Widget::~Widget()
{
    delete ui;
}

// 使用UDP廣播發送信息
void Widget::sendMessage(MessageType type, QString serverAddress)
{
    QByteArray data;
    QDataStream out(&data, QIODevice::WriteOnly);
    QString localHostName = QHostInfo::localHostName();
    QString address = getIP();
    out << type << getUserName() << localHostName;

    switch(type)
    {
    case Message :
        if (ui->messageTextEdit->toPlainText() == "") {
            QMessageBox::warning(0,tr("警告"),tr("發送內容不能爲空"),QMessageBox::Ok);
            return;
        }
        out << address << getMessage();
        ui->messageBrowser->verticalScrollBar()
                ->setValue(ui->messageBrowser->verticalScrollBar()->maximum());
        break;

    case NewParticipant :
        out << address;
        break;

    case ParticipantLeft :
        break;

    case FileName : {
        int row = ui->userTableWidget->currentRow();//必須選中需要發送的給誰纔可以發送
        QString clientAddress = ui->userTableWidget->item(row, 2)->text();//(row,,2)爲ip地址
        out << address << clientAddress << fileName;//發送本地ip,對方ip,所發送的文件名
        break;
    }

    case Refuse :
        out << serverAddress;
        break;
    }
    udpSocket->writeDatagram(data,data.length(),QHostAddress::Broadcast, port);
}

// 接收UDP信息
void Widget::processPendingDatagrams()
{
    while(udpSocket->hasPendingDatagrams())
    {
        QByteArray datagram;
        datagram.resize(udpSocket->pendingDatagramSize());
        udpSocket->readDatagram(datagram.data(), datagram.size());
        QDataStream in(&datagram, QIODevice::ReadOnly);
        int messageType;
        in >> messageType;
        QString userName,localHostName,ipAddress,message;
        QString time = QDateTime::currentDateTime()
                .toString("yyyy-MM-dd hh:mm:ss");

        switch(messageType)
        {
        case Message:
            in >> userName >> localHostName >> ipAddress >> message;
            ui->messageBrowser->setTextColor(Qt::blue);
            ui->messageBrowser->setCurrentFont(QFont("Times New Roman",12));
            ui->messageBrowser->append("[ " +userName+" ] "+ time);
            ui->messageBrowser->append(message);
            break;

        case NewParticipant:
            in >>userName >>localHostName >>ipAddress;
            newParticipant(userName,localHostName,ipAddress);
            break;

        case ParticipantLeft:
            in >>userName >>localHostName;
            participantLeft(userName,localHostName,time);
            break;

        case FileName: {
            in >> userName >> localHostName >> ipAddress;
            QString clientAddress, fileName;
            in >> clientAddress >> fileName;
            hasPendingFile(userName, ipAddress, clientAddress, fileName);
            break;
        }

        case Refuse: {
            in >> userName >> localHostName;
            QString serverAddress;
            in >> serverAddress;
            QString ipAddress = getIP();

            if(ipAddress == serverAddress)
            {
                server->refused();
            }
            break;
        }
        }
    }
}

// 處理新用戶加入
void Widget::newParticipant(QString userName, QString localHostName, QString ipAddress)
{
    bool isEmpty = ui->userTableWidget->findItems(localHostName, Qt::MatchExactly).isEmpty();
    if (isEmpty) {
        QTableWidgetItem *user = new QTableWidgetItem(userName);
        QTableWidgetItem *host = new QTableWidgetItem(localHostName);
        QTableWidgetItem *ip = new QTableWidgetItem(ipAddress);

        ui->userTableWidget->insertRow(0);
        ui->userTableWidget->setItem(0,0,user);
        ui->userTableWidget->setItem(0,1,host);
        ui->userTableWidget->setItem(0,2,ip);
        ui->messageBrowser->setTextColor(Qt::gray);
        ui->messageBrowser->setCurrentFont(QFont("Times New Roman",10));
        ui->messageBrowser->append(tr("%1 在線!").arg(userName));
        ui->userNumLabel->setText(tr("在線人數:%1").arg(ui->userTableWidget->rowCount()));

        sendMessage(NewParticipant);
    }
}

// 處理用戶離開
void Widget::participantLeft(QString userName, QString localHostName, QString time)
{
    int rowNum = ui->userTableWidget->findItems(localHostName, Qt::MatchExactly).first()->row();
    ui->userTableWidget->removeRow(rowNum);
    ui->messageBrowser->setTextColor(Qt::gray);
    ui->messageBrowser->setCurrentFont(QFont("Times New Roman", 10));
    ui->messageBrowser->append(tr("%1 於 %2 離開!").arg(userName).arg(time));
    ui->userNumLabel->setText(tr("在線人數:%1").arg(ui->userTableWidget->rowCount()));
}

// 獲取ip地址
QString Widget::getIP()
{
    QList<QHostAddress> list = QNetworkInterface::allAddresses();
    foreach (QHostAddress address, list) {
        if(address.protocol() == QAbstractSocket::IPv4Protocol)
            return address.toString();
    }
    return 0;
}

// 獲取用戶名
QString Widget::getUserName()
{
    QStringList envVariables;
    envVariables << "USERNAME.*" << "USER.*" << "USERDOMAIN.*"
                 << "HOSTNAME.*" << "DOMAINNAME.*";
    QStringList environment = QProcess::systemEnvironment();
    foreach (QString string, envVariables) {
        int index = environment.indexOf(QRegExp(string));
        if (index != -1) {
            QStringList stringList = environment.at(index).split('=');
            if (stringList.size() == 2) {
                return stringList.at(1);
                break;
            }
        }
    }
    return "unknown";
}

// 獲得要發送的消息
QString Widget::getMessage()
{
    QString msg = ui->messageTextEdit->toHtml();

    ui->messageTextEdit->clear();
    ui->messageTextEdit->setFocus();
    return msg;
}


// 發送消息
void Widget::on_sendButton_clicked()
{
    sendMessage(Message);
}




// 獲取要發送的文件名
void Widget::getFileName(QString name)
{
    fileName = name;
    sendMessage(FileName);
}

// 傳輸文件按鈕
void Widget::on_sendToolBtn_clicked()
{
    if(ui->userTableWidget->selectedItems().isEmpty())//傳送文件前需選擇用戶
    {
        QMessageBox::warning(0, tr("選擇用戶"),
                       tr("請先從用戶列表選擇要傳送的用戶!"), QMessageBox::Ok);
        return;
    }
    server->show();
    server->initServer();
}

// 是否接收文件,客戶端的顯示
void Widget::hasPendingFile(QString userName, QString serverAddress,
                            QString clientAddress, QString fileName)
{
    QString ipAddress = getIP();
    if(ipAddress == clientAddress)
    {
        int btn = QMessageBox::information(this,tr("接受文件"),
                                           tr("來自%1(%2)的文件:%3,是否接收?")
                                           .arg(userName).arg(serverAddress).arg(fileName),
                                           QMessageBox::Yes,QMessageBox::No);//彈出一個窗口
        if (btn == QMessageBox::Yes) {
            QString name = QFileDialog::getSaveFileName(0,tr("保存文件"),fileName);//name爲另存爲的文件名
            if(!name.isEmpty())
            {
                TcpClient *client = new TcpClient(this);
                client->setFileName(name);    //客戶端設置文件名
                client->setHostAddress(QHostAddress(serverAddress));    //客戶端設置服務器地址
                client->show();
            }
        } else {
            sendMessage(Refuse, serverAddress);
        }
    }
}

 

Tcpserver.h:

#ifndef TCPSERVER_H
#define TCPSERVER_H

#include <QDialog>

#include <QTime>
class QFile;
class QTcpServer;
class QTcpSocket;

namespace Ui {
class TcpServer;
}

class TcpServer : public QDialog
{
    Q_OBJECT

public:
    explicit TcpServer(QWidget *parent = 0);
    ~TcpServer();

    void initServer();
    void refused();

protected:
    void closeEvent(QCloseEvent *);

private:
    Ui::TcpServer *ui;

    qint16 tcpPort;
    QTcpServer *tcpServer;
    QString fileName;
    QString theFileName;
    QFile *localFile;

    qint64 TotalBytes;
    qint64 bytesWritten;
    qint64 bytesToWrite;
    qint64 payloadSize;
    QByteArray outBlock;

    QTcpSocket *clientConnection;

    QTime time;

private slots:
    void sendMessage();
    void updateClientProgress(qint64 numBytes);

    void on_serverOpenBtn_clicked();

    void on_serverSendBtn_clicked();

    void on_serverCloseBtn_clicked();

signals:
    void sendFileName(QString fileName);
};

#endif // TCPSERVER_H

 

Tcpserver.cpp:

#include "tcpserver.h"
#include "ui_tcpserver.h"

#include <QFile>
#include <QTcpServer>
#include <QTcpSocket>
#include <QMessageBox>
#include <QFileDialog>
#include <QDebug>

TcpServer::TcpServer(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::TcpServer)
{
    ui->setupUi(this);    //每一個新類都有一個自己的ui

    setFixedSize(350,180);    //初始化時窗口顯示固定大小

    tcpPort = 6666;        //tcp通信端口
    tcpServer = new QTcpServer(this);
    //newConnection表示當tcp有新連接時就發送信號
    connect(tcpServer, SIGNAL(newConnection()), this, SLOT(sendMessage()));

    initServer();
}

TcpServer::~TcpServer()
{
    delete ui;
}

// 初始化
void TcpServer::initServer()
{
    payloadSize = 64*1024;
    TotalBytes = 0;
    bytesWritten = 0;
    bytesToWrite = 0;

    ui->serverStatusLabel->setText(tr("請選擇要傳送的文件"));
    ui->progressBar->reset();//進度條復位
    ui->serverOpenBtn->setEnabled(true);//open按鈕可用
    ui->serverSendBtn->setEnabled(false);//發送按鈕不可用

    tcpServer->close();//tcp傳送文件窗口不顯示
}

// 開始發送數據
void TcpServer::sendMessage()    //是connect中的槽函數
{
    ui->serverSendBtn->setEnabled(false);    //當在傳送文件的過程中,發送按鈕不可用
    clientConnection = tcpServer->nextPendingConnection();    //用來獲取一個已連接的TcpSocket
    //bytesWritten爲qint64類型,即長整型
    connect(clientConnection, SIGNAL(bytesWritten(qint64)),    //?
            this, SLOT(updateClientProgress(qint64)));

    ui->serverStatusLabel->setText(tr("開始傳送文件 %1 !").arg(theFileName));

    localFile = new QFile(fileName);    //localFile代表的是文件內容本身
    if(!localFile->open((QFile::ReadOnly))){
        QMessageBox::warning(this, tr("應用程序"), tr("無法讀取文件 %1:\n%2")
                             .arg(fileName).arg(localFile->errorString()));//errorString是系統自帶的信息
        return;
    }
    TotalBytes = localFile->size();//文件總大小
    //頭文件中的定義QByteArray outBlock;
    QDataStream sendOut(&outBlock, QIODevice::WriteOnly);//設置輸出流屬性
    sendOut.setVersion(QDataStream::Qt_4_7);//設置Qt版本,不同版本的數據流格式不同
    time.start();  // 開始計時
    QString currentFile = fileName.right(fileName.size()    //currentFile代表所選文件的文件名
                                         - fileName.lastIndexOf('/')-1);
    //qint64(0)表示將0轉換成qint64類型,與(qint64)0等價
    //如果是,則此處爲依次寫入總大小信息空間,文件名大小信息空間,文件名
    sendOut << qint64(0) << qint64(0) << currentFile;
    TotalBytes += outBlock.size();//文件名大小等信息+實際文件大小
    //sendOut.device()爲返回io設備的當前設置,seek(0)表示設置當前pos爲0
    sendOut.device()->seek(0);//返回到outBlock的開始,執行覆蓋操作
    //發送總大小空間和文件名大小空間
    sendOut << TotalBytes << qint64((outBlock.size() - sizeof(qint64)*2));
    //qint64 bytesWritten;bytesToWrite表示還剩下的沒發送完的數據
    //clientConnection->write(outBlock)爲套接字將內容發送出去,返回實際發送出去的字節數
    bytesToWrite = TotalBytes - clientConnection->write(outBlock);
    outBlock.resize(0);//why??
}

// 更新進度條,有數據發送時觸發
void TcpServer::updateClientProgress(qint64 numBytes)
{
    //qApp爲指向一個應用對象的全局指針
    qApp->processEvents();//processEvents爲處理所有的事件?
    bytesWritten += (int)numBytes;
    if (bytesToWrite > 0) {    //沒發送完畢
        //初始化時payloadSize = 64*1024;qMin爲返回參數中較小的值,每次最多發送64K的大小
        outBlock = localFile->read(qMin(bytesToWrite, payloadSize));
        bytesToWrite -= (int)clientConnection->write(outBlock);
        outBlock.resize(0);//清空發送緩衝區
    } else {
        localFile->close();
    }
    ui->progressBar->setMaximum(TotalBytes);//進度條的最大值爲所發送信息的所有長度(包括附加信息)
    ui->progressBar->setValue(bytesWritten);//進度條顯示的進度長度爲bytesWritten實時的長度

    float useTime = time.elapsed();//從time.start()還是到當前所用的時間記錄在useTime中
    double speed = bytesWritten / useTime;
    ui->serverStatusLabel->setText(tr("已發送 %1MB (%2MB/s) "
                   "\n共%3MB 已用時:%4秒\n估計剩餘時間:%5秒")
                   .arg(bytesWritten / (1024*1024))    //轉化成MB
                   .arg(speed*1000 / (1024*1024), 0, 'f', 2)
                   .arg(TotalBytes / (1024 * 1024))
                   .arg(useTime/1000, 0, 'f', 0)    //0,‘f’,0是什麼意思啊?
                   .arg(TotalBytes/speed/1000 - useTime/1000, 0, 'f', 0));

    if(bytesWritten == TotalBytes) {    //當需發送文件的總長度等於已發送長度時,表示發送完畢!
        localFile->close();
        tcpServer->close();
        ui->serverStatusLabel->setText(tr("傳送文件 %1 成功").arg(theFileName));
    }
}

// 打開按鈕
void TcpServer::on_serverOpenBtn_clicked()
{
    //QString fileName;QFileDialog是一個提供給用戶選擇文件或目錄的對話框
    fileName = QFileDialog::getOpenFileName(this);    //filename爲所選擇的文件名(包含了路徑名)
    if(!fileName.isEmpty())
    {
        //fileName.right爲返回filename最右邊參數大小個字文件名,theFileName爲所選真正的文件名
        theFileName = fileName.right(fileName.size() - fileName.lastIndexOf('/')-1);
        ui->serverStatusLabel->setText(tr("要傳送的文件爲:%1 ").arg(theFileName));
        ui->serverSendBtn->setEnabled(true);//發送按鈕可用
        ui->serverOpenBtn->setEnabled(false);//open按鈕禁用
    }
}

// 發送按鈕
void TcpServer::on_serverSendBtn_clicked()
{
    //tcpServer->listen函數如果監聽到有連接,則返回1,否則返回0
    if(!tcpServer->listen(QHostAddress::Any,tcpPort))//開始監聽6666端口
    {
        qDebug() << tcpServer->errorString();//此處的errorString是指?
        close();
        return;
    }

    ui->serverStatusLabel->setText(tr("等待對方接收... ..."));
    emit sendFileName(theFileName);//發送已傳送文件的信號,在widget.cpp構造函數中的connect()觸發槽函數
}

// 關閉按鈕,服務器端的關閉按鈕
void TcpServer::on_serverCloseBtn_clicked()
{
    if(tcpServer->isListening())
    {
        //當tcp正在監聽時,關閉tcp服務器端應用,即按下close鍵時就不監聽tcp請求了
        tcpServer->close();
        if (localFile->isOpen())//如果所選擇的文件已經打開,則關閉掉
            localFile->close();
        clientConnection->abort();//clientConnection爲下一個連接?怎麼理解
    }
    close();//關閉本ui,即本對話框
}

// 被對方拒絕
void TcpServer::refused()
{
    tcpServer->close();
    ui->serverStatusLabel->setText(tr("對方拒絕接收!!!"));
}

// 關閉事件
void TcpServer::closeEvent(QCloseEvent *)
{
    on_serverCloseBtn_clicked();
}

 

Tcpclient.h:

#ifndef TCPCLIENT_H
#define TCPCLIENT_H

#include <QDialog>
#include <QHostAddress>
#include <QFile>
#include <QTime>
class QTcpSocket;

namespace Ui {
class TcpClient;
}

class TcpClient : public QDialog
{
    Q_OBJECT

public:
    explicit TcpClient(QWidget *parent = 0);
    ~TcpClient();

    void setHostAddress(QHostAddress address);
    void setFileName(QString fileName);

protected:
    void closeEvent(QCloseEvent *);

private:
    Ui::TcpClient *ui;

    QTcpSocket *tcpClient;
    quint16 blockSize;
    QHostAddress hostAddress;
    qint16 tcpPort;

    qint64 TotalBytes;
    qint64 bytesReceived;
    qint64 bytesToReceive;
    qint64 fileNameSize;
    QString fileName;
    QFile *localFile;
    QByteArray inBlock;

    QTime time;

private slots:
    void on_tcpClientCancleBtn_clicked();
    void on_tcpClientCloseBtn_clicked();

    void newConnect();
    void readMessage();
    void displayError(QAbstractSocket::SocketError);
};

#endif // TCPCLIENT_H

 

Tcpclient.cpp:

#include "tcpclient.h"
#include "ui_tcpclient.h"

#include <QTcpSocket>
#include <QDebug>
#include <QMessageBox>

TcpClient::TcpClient(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::TcpClient)
{
    ui->setupUi(this);

    setFixedSize(350,180);

    TotalBytes = 0;
    bytesReceived = 0;
    fileNameSize = 0;

    tcpClient = new QTcpSocket(this);
    tcpPort = 6666;
    connect(tcpClient, SIGNAL(readyRead()), this, SLOT(readMessage()));
    connect(tcpClient, SIGNAL(error(QAbstractSocket::SocketError)), this,
            SLOT(displayError(QAbstractSocket::SocketError)));
}

TcpClient::~TcpClient()
{
    delete ui;
}

// 設置文件名
void TcpClient::setFileName(QString fileName)
{
    localFile = new QFile(fileName);
}

// 設置地址
void TcpClient::setHostAddress(QHostAddress address)
{
    hostAddress = address;
    newConnect();
}

// 創建新連接
void TcpClient::newConnect()
{
    blockSize = 0;
    tcpClient->abort();        //取消已有的連接
    tcpClient->connectToHost(hostAddress, tcpPort);//連接到指定ip地址和端口的主機
    time.start();
}

// 讀取數據
void TcpClient::readMessage()
{
    QDataStream in(tcpClient);    //這裏的QDataStream可以直接用QTcpSocket對象做參數
    in.setVersion(QDataStream::Qt_4_7);

    float useTime = time.elapsed();

    if (bytesReceived <= sizeof(qint64)*2) {    //說明剛開始接受數據
        if ((tcpClient->bytesAvailable()    //bytesAvailable爲返回將要被讀取的字節數
             >= sizeof(qint64)*2) && (fileNameSize == 0))
        {
            //接受數據總大小信息和文件名大小信息
            in>>TotalBytes>>fileNameSize;
            bytesReceived += sizeof(qint64)*2;
        }
        if((tcpClient->bytesAvailable() >= fileNameSize) && (fileNameSize != 0)){
            //開始接受文件,並建立文件
            in>>fileName;
            bytesReceived +=fileNameSize;

            if(!localFile->open(QFile::WriteOnly)){
                QMessageBox::warning(this,tr("應用程序"),tr("無法讀取文件 %1:\n%2.")
                                     .arg(fileName).arg(localFile->errorString()));
                return;
            }
        } else {
            return;
        }
    }
    if (bytesReceived < TotalBytes) {
        bytesReceived += tcpClient->bytesAvailable();//返回tcpClient中字節的總數
        inBlock = tcpClient->readAll();    //返回讀到的所有數據
        localFile->write(inBlock);
        inBlock.resize(0);
    }
    ui->progressBar->setMaximum(TotalBytes);
    ui->progressBar->setValue(bytesReceived);

    double speed = bytesReceived / useTime;
    ui->tcpClientStatusLabel->setText(tr("已接收 %1MB (%2MB/s) "
                                         "\n共%3MB 已用時:%4秒\n估計剩餘時間:%5秒")
                                      .arg(bytesReceived / (1024*1024))
                                      .arg(speed*1000/(1024*1024),0,'f',2)
                                      .arg(TotalBytes / (1024 * 1024))
                                      .arg(useTime/1000,0,'f',0)
                                      .arg(TotalBytes/speed/1000 - useTime/1000,0,'f',0));

    if(bytesReceived == TotalBytes)
    {
        localFile->close();
        tcpClient->close();
        ui->tcpClientStatusLabel->setText(tr("接收文件 %1 完畢")
                                          .arg(fileName));
    }
}

// 錯誤處理
//QAbstractSocket類提供了所有scoket的通用功能,socketError爲枚舉型
void TcpClient::displayError(QAbstractSocket::SocketError socketError)
{
    switch(socketError)
    {
    //RemoteHostClosedError爲遠處主機關閉了連接時發出的錯誤信號
    case QAbstractSocket::RemoteHostClosedError : break;
    default : qDebug() << tcpClient->errorString();
    }
}

// 取消按鈕
void TcpClient::on_tcpClientCancleBtn_clicked()
{
    tcpClient->abort();
    if (localFile->isOpen())
        localFile->close();
}

// 關閉按鈕
void TcpClient::on_tcpClientCloseBtn_clicked()
{
    tcpClient->abort();
    if (localFile->isOpen())
        localFile->close();
    close();
}

// 關閉事件
void TcpClient::closeEvent(QCloseEvent *)
{
    on_tcpClientCloseBtn_clicked();
}

 

Main.cpp:

#include <QtGui/QApplication>
#include "widget.h"
#include <QTextCodec>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QTextCodec::setCodecForTr(QTextCodec::codecForLocale());
    Widget w;
    w.show();

    return a.exec();
}

 

 

 

 

 

作者:tornadomeet 出處:http://www.cnblogs.com/tornadomeet 歡迎轉載或分享,但請務必聲明文章出處。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章