欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Qt中網(wǎng)絡(luò)編程的實(shí)現(xiàn)

 更新時(shí)間:2022年02月04日 08:51:42   作者:small建攻  
本文主要介紹了Qt中網(wǎng)絡(luò)編程的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

由于我沒有系統(tǒng)的分享一些簡單的計(jì)算機(jī)網(wǎng)絡(luò)有關(guān)的,下面只是簡單講講tcp/ip協(xié)議簇和udp

一、tcp/IP協(xié)議簇與udp      

1、TCP/IP協(xié)議族

        TCP/IP實(shí)際上是一個(gè)協(xié)同工作的通信家族,為網(wǎng)絡(luò)通信提供通路。為方便討論TCP/IP協(xié)議族,大體上分為三部分:

①、Internet協(xié)議(IP)。

②、傳輸控制協(xié)議(TCP)和用戶數(shù)據(jù)報(bào)協(xié)議(UDP)。

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

2、udp

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

3、常用的通訊協(xié)議小結(jié)

1.3.1、tcp/ip

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

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

        現(xiàn)在常用的ip是127.0.0.1這個(gè)樣子,點(diǎn)分格式(一個(gè)字符串)。點(diǎn)所隔開的區(qū)間就是一個(gè)字符。Ip地址有ABC三類地址。前三段是用來確定路由器,確定主機(jī)連上外圍網(wǎng)上的哪一個(gè)路由,最后一段用來確定主機(jī),確定主機(jī)是這個(gè)路由器上的第多少臺(tái),最多255臺(tái),0一般是用來做網(wǎng)關(guān)的。

        ip對(duì)應(yīng)的還有一個(gè)子網(wǎng)掩碼

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

        對(duì)于A類地址來說,默認(rèn)的子網(wǎng)掩碼是255.0.0.0;

        對(duì)于B類地址來說默認(rèn)的子網(wǎng)掩碼是255.255.0.0;

        對(duì)于C類地址來說默認(rèn)的子網(wǎng)掩碼是255.255.255.0。

        子網(wǎng)掩碼,一般是255.255.255.0。

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

1.3.2、Socket

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

        建立網(wǎng)絡(luò)通信連接至少要一對(duì)端口號(hào)(socket)。socket本質(zhì)是編程接口(API),對(duì)TCP/IP的封裝,TCP/IP也要提供可供程序員做網(wǎng)絡(luò)開發(fā)所用的接口,這就是Socket編程接口。通常也稱作"套接字",用于描述IP地址和端口,是一個(gè)通信鏈的句柄,可以用來實(shí)現(xiàn)不同虛擬機(jī)或不同計(jì)算機(jī)之間的通信。

1.3.3、tcp通信模型

        c/s模型,客戶端(c)/服務(wù)器(s)模型,一個(gè)服務(wù)器來對(duì)應(yīng)多個(gè)客戶端的處理,一對(duì)多的關(guān)系。以下步驟沒有特殊指明,服務(wù)器和客戶端是都需要有的步驟:

        1.準(zhǔn)備工作,根據(jù)自己使用語言所有庫函數(shù)導(dǎo)入;

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

        3. 創(chuàng)建socket,使用socket函數(shù)

        4. 初始化協(xié)議地址簇 ;       

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

        6. 服務(wù)器端有,需要監(jiān)聽 listen函數(shù),客戶端不需要這一步;

        7. 服務(wù)器端需要接受連接,客戶端需要連接服務(wù)器;

        8. 連接完成之后,開始通訊,收發(fā)數(shù)據(jù);

        9. 通訊完成后關(guān)閉socket;

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

        開始前在項(xiàng)目的.pro文件中加入這個(gè)network

1、tcpsever

tcpsever.h 

#ifndef WIDGET_H
#define WIDGET_H
 
#include <QWidget>
#include <QNetworkInterface>//網(wǎng)絡(luò)信息
#include <QHostAddress>//id地址
#include <QTcpServer> //tcp協(xié)議
#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、設(shè)置服務(wù)端和接收客戶端的對(duì)象
    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、創(chuàng)建服務(wù)器對(duì)象
    tcpSocket=NULL;
    tcpServer=new QTcpServer(this);
    //5、有客戶端連接服務(wù)器發(fā)送信號(hào)
    connect(tcpServer,
            SIGNAL(newConnection()),
            this,
            SLOT(newconnectslot()));
    QMessageBox::information(this,"本機(jī)聯(lián)網(wǎng)端口顯示",this->list_all_IPV4());
}
 
Widget::~Widget()
{
    delete ui;
}
 
void Widget::on_pushButton_listen_clicked()
{
    //4、開始監(jiān)聽
    QString sever_Address = ui->lineEdit_address->text();
    quint16 port          = ui->lineEdit_port->text().toInt();
    QHostAddress host     = QHostAddress(sever_Address);
    if(!tcpServer->isListening()){
        //監(jiān)聽綁定的ip地址
        if(!tcpServer->listen(host,port))
        {
            qDebug()<<tcpServer->errorString();
            return;
        }else{
            qDebug()<<"監(jiān)聽成功";
            ui->pushButton_listen->setText("停止監(jiān)聽");
        }
    }else{
        tcpServer->close();
        ui->pushButton_listen->setText("開始監(jiān)聽");
    }
}
 
QString Widget::list_all_IPV4(){
            QString str;
            QList<QHostAddress> list=QNetworkInterface::allAddresses();     //獲取本機(jī)的所有網(wǎng)卡的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()
                          +" "+
                          "端口號(hào):"    + QString::number(tcpSocket->peerPort());
    ui->textBrowser_clientInfo->setText(client_Info);
    //發(fā)送信號(hào)和讀取關(guān)聯(lián)
    connect(tcpSocket,
            SIGNAL(readyRead()),
            this,
            SLOT(readyRead_Slot()));
    //斷開信號(hào)關(guān)聯(lián)客戶端
    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的轉(zhuǎn)換
 
            tcpSocket->write(sendarr);
        }
    }
}
 
void Widget::readyRead_Slot(){
    if(tcpSocket != nullptr)
    {
        if(tcpSocket->isReadable())
        {
           QByteArray recvAll = tcpSocket->readAll();//將數(shù)據(jù)全部讀取
 
           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>//網(wǎng)絡(luò)信息
#include <QHostAddress>//id地址
#include <QTcpServer> //tcp協(xié)議
#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,連不上會(huì)返回假
            ui->pushButton_listen->setText("斷開連接");
            socket_state = true;
        }else{
            qDebug()<<client->errorString();
            return;
        }
    }else{
        client->close();
        QMessageBox::information(this,"消息提示","已經(jīng)離開!",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中的Udp

        初始操作同TCP操作

udp_test.h

#ifndef WIDGET_H
#define WIDGET_H
 
#include <QWidget>
 
//1、包含相關(guān)的頭文件
#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對(duì)象
    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、創(chuàng)建對(duì)象
    udpSocket=new QUdpSocket(this);
 
    //4、關(guān)聯(lián)讀取的信號(hào)與槽
    connect(udpSocket,SIGNAL(readyRead()),this,SLOT(readyReadSlot()));
 
}
 
Widget::~Widget()
{
    delete ui;
}
 
void Widget::on_pushButtonSend_clicked()
{
    udpSocket->writeDatagram(ui->plainTextEdit_sendInfo->toPlainText().toLocal8Bit(),//內(nèi)容
                             QHostAddress(ui->lineEditIp->text()),//發(fā)送ip
                             ui->lineEditPort->text().toInt());//發(fā)送的地址
}
 
void Widget::on_pushButtonCLose_clicked()
{
    udpSocket->bind(ui->lineEditPort_2->text().toInt());
}
 
void Widget::readyReadSlot(){
  quint64 size = udpSocket->bytesAvailable();//讀取發(fā)過來的消息大小
  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);
}

 到此這篇關(guān)于Qt中網(wǎng)絡(luò)編程的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Qt網(wǎng)絡(luò)編程內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論