广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >Qt中网络编程的实现
  • 244
分享到

Qt中网络编程的实现

2024-04-02 19:04:59 244人浏览 安东尼
摘要

目录一、tcp/IP协议簇与udp      1、TCP/IP协议族2、udp3、常用的通讯协议小结二、Qt中的tcp(这里只展示代码)1、t

由于我没有系统的分享一些简单的计算机网络有关的,下面只是简单讲讲tcp/ip协议簇和udp

一、tcp/IP协议簇与udp      

1、TCP/IP协议族

        TCP/IP实际上是一个协同工作的通信家族,为网络通信提供通路。为方便讨论TCP/IP协议族,大体上分为三部分:

①、Internet协议(IP)。

②、传输控制协议(TCP)和用户数据报协议(UDP)。

③、处于TCP和UDP之上的一组应用协议。它们包括:Telnet,文件传送协议(FTP),域名服务协议(DNS)和简单的邮件传送程序(SMTP)等。

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

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中的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网络编程内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Qt中网络编程的实现

本文链接: https://www.lsjlt.com/news/138156.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Qt中网络编程的实现
    目录一、tcp/IP协议簇与udp      1、TCP/IP协议族2、udp3、常用的通讯协议小结二、Qt中的tcp(这里只展示代码)1、t...
    99+
    2022-11-13
  • Qt中网络编程怎么实现
    这篇文章主要介绍“Qt中网络编程怎么实现”,在日常操作中,相信很多人在Qt中网络编程怎么实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Qt中网络编程怎么实现”的疑惑有所帮助!接下来,请跟着小编一起来学习吧...
    99+
    2023-06-29
  • Qt多线程实现网络发送文件功能
    本文实例为大家分享了Qt多线程实现网络发送文件功能的具体代码,供大家参考,具体内容如下 客户端给服务器发送文件,服务器进行接收文件的简单操作 1. 服务器 1. 创建QTcpServ...
    99+
    2022-11-13
  • Qt实现网络聊天室的示例代码
    目录1. 效果演示2. 预备知识2.1 QTcpServer2.2 QTcpServer信号2.3 QTcpSocket2.4 QTcpSocket信号3. 通信流程3.1 服务器端...
    99+
    2022-11-12
  • linux 网络编程 socket选项的实现
    socket选项函数 功能:用来读取和设置socket文件描述符属性的方法 #include <sys/scoket.h> int getsockopt ( int sockfd, int level, ...
    99+
    2022-06-04
    linux socket选项
  • C#中怎么实现异步网络编程
    这期内容当中小编将会给大家带来有关C#中怎么实现异步网络编程,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。C#异步网络编程两大方法一、Asynchronous Sockets的方法Socket类的很多连接...
    99+
    2023-06-17
  • Java中怎么使用NIO实现网络编程
    本篇文章为大家展示了Java中怎么使用NIO实现网络编程,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。为什么需要NIO使用Java编写过Socket程序的同学一定都知道Socket和SocketSe...
    99+
    2023-06-17
  • Python中怎么使用Socket实现网络编程
    本篇文章为大家展示了Python中怎么使用Socket实现网络编程,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。Socket:套接字套接字好比电话的插口,主机和端口就好比区号和电话号码,主机:是你要...
    99+
    2023-06-17
  • Java网络编程实现多线程聊天
    本文实例为大家分享了Java网络编程实现多线程聊天的具体代码,供大家参考,具体内容如下 聊天程序如果是单线程,会导致没人只能说一句,并且说了以后,必须等到另一个人的回复,才能说第二句...
    99+
    2022-11-12
  • C++ Socket实现TCP与UDP网络编程
    目录前言TCP1). 服务器2). 客户端3). TCP聊天小项目UDP1). 服务器2). 客户端总结前言 socket编程分为TCP和UDP两个模块,其中TCP是可靠的、安全的,...
    99+
    2022-11-13
  • PHP底层的网络编程与实现技巧
    抱歉,我目前无法为您提供超过900字的文章。但我可以向您展示一些PHP底层网络编程和实现技巧的关键要点和代码示例。请问您需要什么样的内容?...
    99+
    2023-11-08
    网络编程 实现技巧 PHP底层
  • 【Linux网络】网络编程套接字 -- 基于socket实现一个简单UDP网络程序
    认识端口号网络字节序处理字节序函数 htonl、htons、ntohl、ntohs socketsocket编程接口sockaddr结构结尾实现UDP程序的socket接口使用解析so...
    99+
    2023-09-01
    网络 linux udp socket
  • Java网络编程TCP实现聊天功能
    网络编程TCP实现聊天的前提还需要掌握IO流,话不多说,直接上代码! 客户端: package com.kuang.lesson02; import java.io.IOExc...
    99+
    2022-11-12
  • 如何实现Python底层技术的网络编程
    如何实现Python底层技术的网络编程网络编程是现代软件开发中的一个重要技术领域,通过网络编程,我们可以实现应用程序之间的通信,实现跨机器、跨平台的数据传输和交互。Python作为一种广泛使用的编程语言,提供了简洁而强大的底层技术来实现网络...
    99+
    2023-11-08
    Python 网络编程 底层技术
  • Java网络编程之简易聊天室的实现
    目录一、题目描述二、解题思路三、代码详解一、题目描述 题目实现:运行客户端,连接服务器。 二、解题思路 首先需要启动上题的ServerSocketFrame服务,这样客户端运行时,才...
    99+
    2022-11-13
    Java实现简易聊天室 Java 聊天室
  • Java网络编程怎么实现多线程聊天
    这篇文章将为大家详细讲解有关Java网络编程怎么实现多线程聊天,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。聊天程序如果是单线程,会导致没人只能说一句,并且说了以后,必须等到另一个人的回复,才能说第二句。...
    99+
    2023-06-20
  • java编程实现简单的网络爬虫示例过程
    本项目中需要用到两个第三方jar包,分别为 jsoup 和 commons-io。 jsoup的作用是为了解析网页, commons-io 是为了把数据保存到本地。 1.爬取贴吧 第...
    99+
    2022-11-12
  • Java网络编程中线程的使用
    本篇内容介绍了“Java网络编程中线程的使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!目录运行线程回调同步方法同步块死锁优先级暂停可以对...
    99+
    2023-06-20
  • Go语言网络编程:Go实现简单的内网穿透
    一、内网穿透 1. 内网穿透介绍 内网穿透是一种通过互联网建立远程连接到私有网络(内网)中设备的技术。通常情况下,内网设备由于位于一个受限制的网络环境中,无法直接从外部访问。内网穿透通过将内网设备的流...
    99+
    2023-09-02
    golang 服务器 计算机网络
  • Java网络编程之UDP实现原理解析
    UDP实现通信非常简单,没有服务器,每个都是客户端,每个客户端都需要一个发送端口和一个接收端口。一个客户端向另一个客户端发送消息时,需要知道对方的IP和接收端口,所用到的类为Data...
    99+
    2022-11-12
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作