Qt Tcp網絡助手

效果圖

1、在項目管理文件(.pro) 裏面添加 

QT       += network  //加入網絡模塊

2、引用頭文件

#include <QTcpServer>  //建立Tcp通信應用程序
#include <QTcpSocket>   //建立Tcp通信套接字

3、界面設計

  3.1 服務器UI

3.1 客戶端UI

4、定義一些Tcp通信用到的類

    QTcpServer *server;        //Tcp服務器監聽套接字
    QTcpSocket *socket;        //Tcp服務器通信套接字
    QTcpSocket *client;        //Tcp客戶端

5、在構造函數裏面,爲指針分配空間,並獲取本地Ip地址

network::network(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::network)
{
    ui->setupUi(this);
   
    server = new QTcpServer(this);        //Tcp服務器監聽套接字
    socket = new QTcpSocket(this);       //Tcp服務器通信套接字
    socket = NULL;
    client = new QTcpSocket(this);        //創建一個客戶端
   
    Get_LocalIp();  //獲取本地IP地址
    
    //未連接時失能 發送  按鈕
    ui->TcpServersend_button->setEnabled(false);
    ui->tcpclientsend_button->setEnabled(false);
}

6、服務器端的編程

6.1、獲取本地Ip的方法

//獲取本地Ip
void network::Get_LocalIp()
{
    QString hostName=QHostInfo::localHostName();            //本地主機名
    QHostInfo   hostInfo=QHostInfo::fromName(hostName); //本機IP地址
    QList<QHostAddress> addList=hostInfo.addresses();      //IP地址列表
    for (int i=0;i<addList.count();i++)
    {
        QHostAddress aHost=addList.at(i); //每一項是一個QHostAddress
        if(QAbstractSocket::IPv4Protocol==aHost.protocol())
        {
            ui->tcplisen_ip->setText(aHost.toString()); //顯示出Ip地址
            break;
        }
     }
}

6.2、端口監聽

void network::on_tcplisten_Button_clicked()
{
        if(server->isListening()==true)      //若服務器正在監聽
        {
            if(socket !=NULL)                           //判斷是否已有客戶端連接
                socket->disconnectFromHost();   //斷開與客戶端的連接

            server->close();                               //關閉服務器

            QString str = "停止監聽成功";                 //消息框提示信息
            ui->TcpServer_receive->append(str);
            ui->tcplisten_Button->setText("監聽");      //改變按鈕的提示文字
            ui->LisenState->setText("已停止監聽");   //狀態欄改變連接狀態
            disconnect(server , &QTcpServer::newConnection , this , &network::deal_NewConnection);
        }
        else            //若服務器未監聽
        {
            quint16 port=ui->tcplisen_port->text().toInt(); //獲取監聽的端口號
            QString ip = ui->tcplisen_ip->text();               //獲取監聽的Ip
            server->listen(QHostAddress(ip),port);           //監聽 設置的Ip
//            server->listen(QHostAddress::Any,port);     //監聽 所有的Ip
            ui->tcplisten_Button->setText("停止");           //改變按鈕的提示文字
            ui->LisenState->setText("正在監聽");            //狀態欄改變連接狀態

            //建立連接時會發送 newConnection 信號,關聯對應的處理槽函數
            connect(server , &QTcpServer::newConnection , this , &network::deal_NewConnection);
        }
}

6.3、有客戶端接入時處理函數

void network::deal_NewConnection()
{
    //獲取通信套接字
    socket = server->nextPendingConnection();
    //獲取對方的IP地址 端口號
    QString ip = socket->peerAddress().toString();
    quint16 port = socket->peerPort();
    //消息框提示連接成功
    QString package = QString("[%1:%2] 成功連接").arg(ip).arg(port);
    ui->TcpServer_receive->append(package);

    ui->SocketState->setText("Connected");
    // 關聯接受到客戶端消息時的處理槽函數
    connect(socket , &QTcpSocket::readyRead , this , &network::deal_readyRead);
    //關聯斷開連接時的處理槽函數
    connect(socket , &QTcpSocket::disconnected , this, &network::deal_disconnect);
    //使能發送按鈕
     ui->TcpServersend_button->setEnabled(true);
}

6.4、讀取客戶端發來的信息

/*
 * 若設置爲監聽所有ip 則獲得的 ip 格式爲  "::ffff:xxx.xxx.xxx.xxx"
 * 可通過 ip = ip.mid(7);  來截取指定位置字符 ,使得 ip =  "xxx.xxx.xxx.xxx"
 *
 * 若設置爲監聽特定ip 則獲得的 ip 格式爲  "xxx.xxx.xxx.xxx"
 */
void network::deal_readyRead()
{
    QString ip = socket->peerAddress().toString();      //  獲取客戶端 IP地址
    quint16 port = socket->peerPort();                        //  獲取客戶端 端口號
    QString data = socket->readAll().data();               //  獲取客戶端 發來的數據
    // 數據打包 顯示
    data = QString("[%1:%2] \n%3").arg(ip).arg(port).arg(data);
    ui->TcpServer_receive->append(data);
}

6.5、客戶端斷開連接處理函數,主要是一些提示信息

void network::deal_disconnect()
{
    //消息框提示
    QString ip = socket->peerAddress().toString();
    quint16 port = socket->peerPort();
    QString package = QString("[%1:%2] 已斷開").arg(ip).arg(port);
    ui->TcpServer_receive->append(package);
    //狀態欄信息更新
    ui->SocketState->setText("Disconnected");
    ui->TcpServersend_button->setEnabled(false);

    socket->close();
}

7、客戶端的編程

7.1、與服務器連接

void network::on_connectserver_Button_clicked()
{
        if(client->state()==QAbstractSocket::UnconnectedState)  //與服務器未連接
        {
            QString ip = ui->serverIp_Edit->text();                     //獲取要連接的服務器IP
            quint16 port = ui->serverport_Edit->text().toInt();     //獲取要連接的服務器端口號

            client->connectToHost(QHostAddress(ip),port);       //主動和服務器建立連接

            if(client->waitForConnected(2000)==true)            //等待與服務器建立連接 等待2s
            {
                QString str="成功和服務器連接";
                ui->TcpClient_receive->append(str);

                ui->connectState->setText("已連接");
                ui->connectserver_Button->setText("斷開");
                ui->tcpclientsend_button->setEnabled(true);

                connect(client , &QTcpSocket::readyRead, this , &network::deal_ClientRead);
                connect(client,&QTcpSocket::disconnected,this,&network::deal_Clientdisconnect);                             //
            }
            else                //連接失敗
            {
                QString str="和服務器連接失敗";
                ui->TcpClient_receive->append(str);
            }
        }
        else if(client->state()==QAbstractSocket::ConnectedState) //與服務器已連接
        {
            client->disconnectFromHost();    //主動與服務器斷開連接
        }
}

7.2、讀取收到的數據

void network::deal_ClientRead()
{
    //獲取接收到的數據  
    QString data = client->readAll().data();
    //獲取IP地址
    QString ip = client->peerAddress().toString();
    //獲取端口號
    quint16 port = client->peerPort();

    data = QString("[%1:%2] \n%3").arg(ip).arg(port).arg(data);
    ui->TcpClient_receive->append(data);
}

7.3、主動與服務器斷開處理函數

void network::deal_Clientdisconnect()
{
    client->close();
    QString str="成功和服務器斷開";
    ui->TcpClient_receive->append(str);

    ui->connectState->setText("已斷開");
    ui->connectserver_Button->setText("連接");
    ui->tcpclientsend_button->setEnabled(false);
    //  斷開信號和槽的關聯   
    disconnect(client , &QTcpSocket::readyRead, this , &network::deal_ClientRead);
    disconnect(client,&QTcpSocket::disconnected,this,&network::deal_Clientdisconnect);
}

7.4、發送數據

void network::on_tcpclientsend_button_clicked()
{
        QString data = ui->TcpClient_send->toPlainText();   //獲取發送的內容
        client->write(data.toUtf8().data());                // 發送
}

7.5、清除顯示的內容

void network::on_clear_clientReceive_clicked()
{
    ui->TcpClient_receive->clear();
}

void network::on_clear_clientSend_clicked()
{
    ui->TcpClient_send->clear();
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章