中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Qt中網絡編程怎么實現

發布時間:2022-02-07 10:09:58 來源:億速云 閱讀:158 作者:iii 欄目:開發技術

這篇文章主要介紹“Qt中網絡編程怎么實現”,在日常操作中,相信很多人在Qt中網絡編程怎么實現問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Qt中網絡編程怎么實現”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

一、tcp/IP協議簇與udp      

1、TCP/IP協議族

        TCP/IP實際上是一個協同工作的通信家族,為網絡通信提供通路。為方便討論TCP/IP協議族,大體上分為三部分:

①、Internet協議(IP)。

②、傳輸控制協議(TCP)和用戶數據報協議(UDP)。

③、處于TCP和UDP之上的一組應用協議。它們包括:Telnet,文件傳送協議(FTP),域名服務協議(DNS)和簡單的郵件傳送程序(SMTP)等。

Qt中網絡編程怎么實現

2、udp

        udp協議(用戶數據報協議),它與TCP協議完全相反。提供不可靠、無連接和基于數據報的服務。不可靠意味著UDP協議無法保證數據從發送端正確的發送到接收端。如果數據在中途丟失,或者目的端通過數據校驗發現數據錯誤而將其丟棄,則UDP協議的應用程序通常要自己處理數據確認、超時重傳等邏輯性。

3、常用的通訊協議小結

1.3.1、tcp/ip

        tcp只需要知道它是一種通訊方式就可以了,還有一個udp,那這兩者之間的關系是什么。TCP/IP協議是一個協議簇。里面包括很多協議的。UDP只是其中的一個。之所以命名為TCP/IP協議,因為TCP,IP協議是兩個很重要的協議,就用他兩命名了,tcp是打電話,udp是發短信。

        Ip(網絡之間互連的協議,外文是Internet Protocol的外語縮寫,中文縮寫為“網協”。縮寫為IP),通過設置ip地址就可以去訪問網絡,用的最多的ip協議是ipv4(ip協議v版本4),還有一個版本為ipv6,ipv4不夠用了,Ipv4版本是32位的,一般分成4段,內存中就是一個無符號32位的整數,ipv6的話就是一個64位的整數,通過位數就知道ipv4和ipv6的區別,能保存多少個的地址。只不過用戶并不需要去搞清楚。

        現在常用的ip是127.0.0.1這個樣子,點分格式(一個字符串)。點所隔開的區間就是一個字符。Ip地址有ABC三類地址。前三段是用來確定路由器,確定主機連上外圍網上的哪一個路由,最后一段用來確定主機,確定主機是這個路由器上的第多少臺,最多255臺,0一般是用來做網關的。

        ip對應的還有一個子網掩碼

        子網掩碼(subnet mask)又叫網絡掩碼、地址掩碼、子網絡遮罩,它是一種用來指明一個IP地址的哪些位標識的是主機所在的子網,以及哪些位標識的是主機的位掩碼。子網掩碼不能單獨存在,它必須結合IP地址一起使用。子網掩碼只有一個作用,就是將某個IP地址劃分成網絡地址和主機地址兩部分。子網掩碼--屏蔽一個IP地址的網絡部分的"全1"比特模式。

        對于A類地址來說,默認的子網掩碼是255.0.0.0;

        對于B類地址來說默認的子網掩碼是255.255.0.0;

        對于C類地址來說默認的子網掩碼是255.255.255.0。

        子網掩碼,一般是255.255.255.0。

        ip地址的前三段來確定路由器,最后一段是主機位置。所以子網掩碼理解為子網遮罩編碼。

1.3.2、Socket

        pc機對應在網絡上就是一臺主機,在這臺Pc機上面會有多個進程需要訪問網絡,所以需要在Pc機的操作系統上面去有處理網絡的東西,前人就定了一個“套接字”來專門處理網絡(源IP地址和目的IP地址以及源端口號和目的端口號的組合稱為套接字)。把一個主機拆分為N個網絡端口(Port)一共會有65536個,short的最大范圍,在這些端口當中,要注意0-5000的端口一般不用,用來給操作系統的進程來使用的。一般會用靠后一點的端口,這樣比較安全,當然還有一些端口,比如8080端口也會用的比較多,一個進程只能占用一個端口,不能多進程占用同一個端口的情況,一個進程可以占用多個端口的,或者嚴謹一點,同一時刻一個端口只能由一個進程使用。網絡上的兩個程序通過一個雙向的通信連接實現數據的交換,這個連接的一端稱為一個socket。

        建立網絡通信連接至少要一對端口號(socket)。socket本質是編程接口(API),對TCP/IP的封裝,TCP/IP也要提供可供程序員做網絡開發所用的接口,這就是Socket編程接口。通常也稱作"套接字",用于描述IP地址和端口,是一個通信鏈的句柄,可以用來實現不同虛擬機或不同計算機之間的通信。

1.3.3、tcp通信模型

        c/s模型,客戶端(c)/服務器(s)模型,一個服務器來對應多個客戶端的處理,一對多的關系。以下步驟沒有特殊指明,服務器和客戶端是都需要有的步驟:

        1.準備工作,根據自己使用語言所有庫函數導入;

        2. 確定版本信息,要確定socket版本,ip是有v4和v6兩個版本的;

        3. 創建socket,使用socket函數

        4. 初始化協議地址簇 ;       

        5. 綁定,使用bind函數,把協議地址簇和socket綁定在一起,客戶端不要綁定;

        6. 服務器端有,需要監聽 listen函數,客戶端不需要這一步;

        7. 服務器端需要接受連接,客戶端需要連接服務器;

        8. 連接完成之后,開始通訊,收發數據;

        9. 通訊完成后關閉socket;

二、Qt中的tcp(這里只展示代碼)

        開始前在項目的.pro文件中加入這個network

Qt中網絡編程怎么實現

1、tcpsever

tcpsever.h 

#ifndef WIDGET_H
#define WIDGET_H
 
#include <QWidget>
#include <QNetworkInterface>//網絡信息
#include <QHostAddress>//id地址
#include <QTcpServer> //tcp協議
#include <QTcpSocket> //socket套接字
#include <QDebug>
#include <QMessageBox>
namespace Ui {
class Widget;
}
 
class Widget : public QWidget
{
    Q_OBJECT
 
public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
 
private slots:
    void on_pushButton_listen_clicked();
 
    void on_pushButton_send_clicked();
    void newconnectslot();//連接
    void readyRead_Slot();//讀取信息
    void disconnected_Slot();//斷開
private slots:
    QString list_all_IPV4();
 
private:
    Ui::Widget *ui;
    //2、設置服務端和接收客戶端的對象
    QTcpServer *tcpServer;
    QTcpSocket *tcpSocket;
};
 
#endif // WIDGET_H

 tcpsever.cpp

#include "widget.h"
#include "ui_widget.h"
 
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    //3、創建服務器對象
    tcpSocket=NULL;
    tcpServer=new QTcpServer(this);
    //5、有客戶端連接服務器發送信號
    connect(tcpServer,
            SIGNAL(newConnection()),
            this,
            SLOT(newconnectslot()));
    QMessageBox::information(this,"本機聯網端口顯示",this->list_all_IPV4());
}
 
Widget::~Widget()
{
    delete ui;
}
 
void Widget::on_pushButton_listen_clicked()
{
    //4、開始監聽
    QString sever_Address = ui->lineEdit_address->text();
    quint16 port          = ui->lineEdit_port->text().toInt();
    QHostAddress host     = QHostAddress(sever_Address);
    if(!tcpServer->isListening()){
        //監聽綁定的ip地址
        if(!tcpServer->listen(host,port))
        {
            qDebug()<<tcpServer->errorString();
            return;
        }else{
            qDebug()<<"監聽成功";
            ui->pushButton_listen->setText("停止監聽");
        }
    }else{
        tcpServer->close();
        ui->pushButton_listen->setText("開始監聽");
    }
}
 
QString Widget::list_all_IPV4(){
            QString str;
            QList<QHostAddress> list=QNetworkInterface::allAddresses();     //獲取本機的所有網卡的ip地址
            foreach (QHostAddress address, list)
            {
                if(address.isNull())
                    continue;
                QAbstractSocket::NetworkLayerProtocol portocol=address.protocol();
                //只提取IPv4地址
                if(portocol!=QAbstractSocket::IPv4Protocol)
                    continue;
 
                str = str +'\n\t'+address.toString() + '\n\t\t';
            }
            return str;
};
 
void Widget::newconnectslot(){
    //6、接受客戶端
    tcpSocket = tcpServer->nextPendingConnection();
    QString client_Info = "客戶端:" + tcpSocket->peerAddress().toString()
                          +" "+
                          "端口號:"    + QString::number(tcpSocket->peerPort());
    ui->textBrowser_clientInfo->setText(client_Info);
    //發送信號和讀取關聯
    connect(tcpSocket,
            SIGNAL(readyRead()),
            this,
            SLOT(readyRead_Slot()));
    //斷開信號關聯客戶端
    connect(tcpSocket,
            SIGNAL(disconnected()),
            this,
            SLOT(disconnected_Slot()));
};
 
void Widget::on_pushButton_send_clicked()
{
    if(tcpSocket != nullptr)
    {
        if(tcpSocket->isWritable())
        {
            QString send = ui->plainTextEdit_sendInfo->toPlainText();
 
            QByteArray sendarr = send.toLocal8Bit();//本地字符集與Unicode的轉換
 
            tcpSocket->write(sendarr);
        }
    }
}
 
void Widget::readyRead_Slot(){
    if(tcpSocket != nullptr)
    {
        if(tcpSocket->isReadable())
        {
           QByteArray recvAll = tcpSocket->readAll();//將數據全部讀取
 
           QString str = str.fromLocal8Bit(recvAll.data());
 
           ui->textBrowser_recv->append(str);
        }
    }
 
};
 
void Widget::disconnected_Slot(){
    QMessageBox::information(this,"Client Close Signal","有客戶離開");
};

2、tcpclient

 tcpclient,h

#ifndef WIDGET_H
#define WIDGET_H
 
#include <QWidget>
#include <QNetworkInterface>//網絡信息
#include <QHostAddress>//id地址
#include <QTcpServer> //tcp協議
#include <QTcpSocket> //socket套接字
#include <QDebug>
#include <QMessageBox>
namespace Ui {
class Widget;
}
 
class Widget : public QWidget
{
    Q_OBJECT
 
public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
 
private slots:
    void on_pushButton_listen_clicked();
    void on_pushButton_send_clicked();
 
    void readyRead_Slot();//讀取信息
    void disconnected_Slot();//斷開
 
private:
    Ui::Widget *ui;
    QTcpSocket *client;
    bool socket_state;
};
 
#endif // WIDGET_H

 tcpclient.cpp

#include "widget.h"
#include "ui_widget.h"
 
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    client = new QTcpSocket(this);
    socket_state = false;
 
    connect(client,
            SIGNAL(disconnected()),
            this,
            SLOT(disconnected_Slot()));
 
    connect(client,
            SIGNAL(readyRead()),
            this,
            SLOT(readyRead_Slot()));
}
 
Widget::~Widget()
{
    delete ui;
}
 
 
void Widget::on_pushButton_listen_clicked()
{
    QString ipAddress = ui->lineEdit_address->text();
    qint16 port = ui->lineEdit_port->text().toInt();
 
    if(!socket_state)
    {
        client->connectToHost(ipAddress,port);
        if(client->waitForConnected(3000)){//等待3s,連不上會返回假
            ui->pushButton_listen->setText("斷開連接");
            socket_state = true;
        }else{
            qDebug()<<client->errorString();
            return;
        }
    }else{
        client->close();
        QMessageBox::information(this,"消息提示","已經離開!",QMessageBox::Yes);
        ui->pushButton_listen->setText("連接");
        socket_state = false;
    }
}
 
void Widget::readyRead_Slot(){
    QByteArray data=client->readAll();
    QString str=str.fromLocal8Bit(data.data());
    ui->textBrowser_recv->append(str);
 
};
 
void Widget::disconnected_Slot(){
     qDebug()<<"離開";
}
 
void Widget::on_pushButton_send_clicked()
{
    QString datastr = ui->plainTextEdit_sendInfo->toPlainText();
    QByteArray da = datastr.toLocal8Bit();
 
    if(client->isOpen() && client->isValid()){
        client->write(da);
    }
}

Qt中網絡編程怎么實現

三、QT中的Udp

        初始操作同TCP操作

udp_test.h

#ifndef WIDGET_H
#define WIDGET_H
 
#include <QWidget>
 
//1、包含相關的頭文件
#include <QHostAddress>
#include <QUdpSocket>
#include <QDebug>
 
namespace Ui {
class Widget;
}
 
class Widget : public QWidget
{
    Q_OBJECT
 
public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
 
private slots:
    void on_pushButtonSend_clicked();
    void readyReadSlot();
    void on_pushButtonCLose_clicked();
 
private:
    Ui::Widget *ui;
    //2、定義udp對象
    QUdpSocket *udpSocket;
};
 
#endif // WIDGET_H

udp_test.cpp

#include "widget.h"
#include "ui_widget.h"
 
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    //3、創建對象
    udpSocket=new QUdpSocket(this);
 
    //4、關聯讀取的信號與槽
    connect(udpSocket,SIGNAL(readyRead()),this,SLOT(readyReadSlot()));
 
}
 
Widget::~Widget()
{
    delete ui;
}
 
void Widget::on_pushButtonSend_clicked()
{
    udpSocket->writeDatagram(ui->plainTextEdit_sendInfo->toPlainText().toLocal8Bit(),//內容
                             QHostAddress(ui->lineEditIp->text()),//發送ip
                             ui->lineEditPort->text().toInt());//發送的地址
}
 
void Widget::on_pushButtonCLose_clicked()
{
    udpSocket->bind(ui->lineEditPort_2->text().toInt());
}
 
void Widget::readyReadSlot(){
  quint64 size = udpSocket->bytesAvailable();//讀取發過來的消息大小
  QByteArray ba;
  ba.resize(size);
  QHostAddress address;
  quint16 port;
 
  udpSocket->readDatagram(ba.data(),size,&address,&port);
  QString str = QString::fromLocal8Bit(ba.data());
 
  ui->textEdit_recvInfo->append(str);
}

Qt中網絡編程怎么實現

到此,關于“Qt中網絡編程怎么實現”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

qt
AI

南陵县| 浦江县| 临朐县| 全南县| 勃利县| 定南县| 息烽县| 独山县| 昭觉县| 赤壁市| 威海市| 满洲里市| 安化县| 旬邑县| 金阳县| 浦城县| 哈尔滨市| 灵山县| 丰城市| 凤城市| 成都市| 凤阳县| 略阳县| 禄劝| 韩城市| 宁晋县| 柞水县| 公安县| 元氏县| 祁连县| 阳城县| 韶山市| 横山县| 灌云县| 德令哈市| 津市市| 都安| 金秀| 东乡族自治县| 新巴尔虎右旗| 资源县|