当前位置:   article > 正文

Qt中的网络编程_qt网络编程

qt网络编程

目录

一、tcp/IP协议簇与udp      

1、TCP/IP协议族

2、udp

3、常用的通讯协议小结

1.3.1、tcp/ip

1.3.2、Socket

1.3.3、tcp通信模型

二、Qt中的tcp(这里只展示代码)

1、tcpsever

2、tcpclient

​三、QT中的Udp


      由于我没有系统的分享一些简单的计算机网络有关的,下面只是简单讲讲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(127.0.0.1_百度百科 (baidu.com))这个样子,点分格式(一个字符串)。点所隔开的区间就是一个字符。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 

  1. #ifndef WIDGET_H
  2. #define WIDGET_H
  3. #include <QWidget>
  4. #include <QNetworkInterface>//网络信息
  5. #include <QHostAddress>//id地址
  6. #include <QTcpServer> //tcp协议
  7. #include <QTcpSocket> //socket套接字
  8. #include <QDebug>
  9. #include <QMessageBox>
  10. namespace Ui {
  11. class Widget;
  12. }
  13. class Widget : public QWidget
  14. {
  15. Q_OBJECT
  16. public:
  17. explicit Widget(QWidget *parent = 0);
  18. ~Widget();
  19. private slots:
  20. void on_pushButton_listen_clicked();
  21. void on_pushButton_send_clicked();
  22. void newconnectslot();//连接
  23. void readyRead_Slot();//读取信息
  24. void disconnected_Slot();//断开
  25. private slots:
  26. QString list_all_IPV4();
  27. private:
  28. Ui::Widget *ui;
  29. //2、设置服务端和接收客户端的对象
  30. QTcpServer *tcpServer;
  31. QTcpSocket *tcpSocket;
  32. };
  33. #endif // WIDGET_H

 tcpsever.cpp

  1. #include "widget.h"
  2. #include "ui_widget.h"
  3. Widget::Widget(QWidget *parent) :
  4. QWidget(parent),
  5. ui(new Ui::Widget)
  6. {
  7. ui->setupUi(this);
  8. //3、创建服务器对象
  9. tcpSocket=NULL;
  10. tcpServer=new QTcpServer(this);
  11. //5、有客户端连接服务器发送信号
  12. connect(tcpServer,
  13. SIGNAL(newConnection()),
  14. this,
  15. SLOT(newconnectslot()));
  16. QMessageBox::information(this,"本机联网端口显示",this->list_all_IPV4());
  17. }
  18. Widget::~Widget()
  19. {
  20. delete ui;
  21. }
  22. void Widget::on_pushButton_listen_clicked()
  23. {
  24. //4、开始监听
  25. QString sever_Address = ui->lineEdit_address->text();
  26. quint16 port = ui->lineEdit_port->text().toInt();
  27. QHostAddress host = QHostAddress(sever_Address);
  28. if(!tcpServer->isListening()){
  29. //监听绑定的ip地址
  30. if(!tcpServer->listen(host,port))
  31. {
  32. qDebug()<<tcpServer->errorString();
  33. return;
  34. }else{
  35. qDebug()<<"监听成功";
  36. ui->pushButton_listen->setText("停止监听");
  37. }
  38. }else{
  39. tcpServer->close();
  40. ui->pushButton_listen->setText("开始监听");
  41. }
  42. }
  43. QString Widget::list_all_IPV4(){
  44. QString str;
  45. QList<QHostAddress> list=QNetworkInterface::allAddresses(); //获取本机的所有网卡的ip地址
  46. foreach (QHostAddress address, list)
  47. {
  48. if(address.isNull())
  49. continue;
  50. QAbstractSocket::NetworkLayerProtocol portocol=address.protocol();
  51. //只提取IPv4地址
  52. if(portocol!=QAbstractSocket::IPv4Protocol)
  53. continue;
  54. str = str +'\n\t'+address.toString() + '\n\t\t';
  55. }
  56. return str;
  57. };
  58. void Widget::newconnectslot(){
  59. //6、接受客户端
  60. tcpSocket = tcpServer->nextPendingConnection();
  61. QString client_Info = "客户端:" + tcpSocket->peerAddress().toString()
  62. +" "+
  63. "端口号:" + QString::number(tcpSocket->peerPort());
  64. ui->textBrowser_clientInfo->setText(client_Info);
  65. //发送信号和读取关联
  66. connect(tcpSocket,
  67. SIGNAL(readyRead()),
  68. this,
  69. SLOT(readyRead_Slot()));
  70. //断开信号关联客户端
  71. connect(tcpSocket,
  72. SIGNAL(disconnected()),
  73. this,
  74. SLOT(disconnected_Slot()));
  75. };
  76. void Widget::on_pushButton_send_clicked()
  77. {
  78. if(tcpSocket != nullptr)
  79. {
  80. if(tcpSocket->isWritable())
  81. {
  82. QString send = ui->plainTextEdit_sendInfo->toPlainText();
  83. QByteArray sendarr = send.toLocal8Bit();//本地字符集与Unicode的转换
  84. tcpSocket->write(sendarr);
  85. }
  86. }
  87. }
  88. void Widget::readyRead_Slot(){
  89. if(tcpSocket != nullptr)
  90. {
  91. if(tcpSocket->isReadable())
  92. {
  93. QByteArray recvAll = tcpSocket->readAll();//将数据全部读取
  94. QString str = str.fromLocal8Bit(recvAll.data());
  95. ui->textBrowser_recv->append(str);
  96. }
  97. }
  98. };
  99. void Widget::disconnected_Slot(){
  100. QMessageBox::information(this,"Client Close Signal","有客户离开");
  101. };

2、tcpclient

 tcpclient,h

  1. #ifndef WIDGET_H
  2. #define WIDGET_H
  3. #include <QWidget>
  4. #include <QNetworkInterface>//网络信息
  5. #include <QHostAddress>//id地址
  6. #include <QTcpServer> //tcp协议
  7. #include <QTcpSocket> //socket套接字
  8. #include <QDebug>
  9. #include <QMessageBox>
  10. namespace Ui {
  11. class Widget;
  12. }
  13. class Widget : public QWidget
  14. {
  15. Q_OBJECT
  16. public:
  17. explicit Widget(QWidget *parent = 0);
  18. ~Widget();
  19. private slots:
  20. void on_pushButton_listen_clicked();
  21. void on_pushButton_send_clicked();
  22. void readyRead_Slot();//读取信息
  23. void disconnected_Slot();//断开
  24. private:
  25. Ui::Widget *ui;
  26. QTcpSocket *client;
  27. bool socket_state;
  28. };
  29. #endif // WIDGET_H

 tcpclient.cpp

  1. #include "widget.h"
  2. #include "ui_widget.h"
  3. Widget::Widget(QWidget *parent) :
  4. QWidget(parent),
  5. ui(new Ui::Widget)
  6. {
  7. ui->setupUi(this);
  8. client = new QTcpSocket(this);
  9. socket_state = false;
  10. connect(client,
  11. SIGNAL(disconnected()),
  12. this,
  13. SLOT(disconnected_Slot()));
  14. connect(client,
  15. SIGNAL(readyRead()),
  16. this,
  17. SLOT(readyRead_Slot()));
  18. }
  19. Widget::~Widget()
  20. {
  21. delete ui;
  22. }
  23. void Widget::on_pushButton_listen_clicked()
  24. {
  25. QString ipAddress = ui->lineEdit_address->text();
  26. qint16 port = ui->lineEdit_port->text().toInt();
  27. if(!socket_state)
  28. {
  29. client->connectToHost(ipAddress,port);
  30. if(client->waitForConnected(3000)){//等待3s,连不上会返回假
  31. ui->pushButton_listen->setText("断开连接");
  32. socket_state = true;
  33. }else{
  34. qDebug()<<client->errorString();
  35. return;
  36. }
  37. }else{
  38. client->close();
  39. QMessageBox::information(this,"消息提示","已经离开!",QMessageBox::Yes);
  40. ui->pushButton_listen->setText("连接");
  41. socket_state = false;
  42. }
  43. }
  44. void Widget::readyRead_Slot(){
  45. QByteArray data=client->readAll();
  46. QString str=str.fromLocal8Bit(data.data());
  47. ui->textBrowser_recv->append(str);
  48. };
  49. void Widget::disconnected_Slot(){
  50. qDebug()<<"离开";
  51. }
  52. void Widget::on_pushButton_send_clicked()
  53. {
  54. QString datastr = ui->plainTextEdit_sendInfo->toPlainText();
  55. QByteArray da = datastr.toLocal8Bit();
  56. if(client->isOpen() && client->isValid()){
  57. client->write(da);
  58. }
  59. }

三、QT中的Udp

        初始操作同TCP操作

udp_test.h

  1. #ifndef WIDGET_H
  2. #define WIDGET_H
  3. #include <QWidget>
  4. //1、包含相关的头文件
  5. #include <QHostAddress>
  6. #include <QUdpSocket>
  7. #include <QDebug>
  8. namespace Ui {
  9. class Widget;
  10. }
  11. class Widget : public QWidget
  12. {
  13. Q_OBJECT
  14. public:
  15. explicit Widget(QWidget *parent = 0);
  16. ~Widget();
  17. private slots:
  18. void on_pushButtonSend_clicked();
  19. void readyReadSlot();
  20. void on_pushButtonCLose_clicked();
  21. private:
  22. Ui::Widget *ui;
  23. //2、定义udp对象
  24. QUdpSocket *udpSocket;
  25. };
  26. #endif // WIDGET_H

udp_test.cpp

  1. #include "widget.h"
  2. #include "ui_widget.h"
  3. Widget::Widget(QWidget *parent) :
  4. QWidget(parent),
  5. ui(new Ui::Widget)
  6. {
  7. ui->setupUi(this);
  8. //3、创建对象
  9. udpSocket=new QUdpSocket(this);
  10. //4、关联读取的信号与槽
  11. connect(udpSocket,SIGNAL(readyRead()),this,SLOT(readyReadSlot()));
  12. }
  13. Widget::~Widget()
  14. {
  15. delete ui;
  16. }
  17. void Widget::on_pushButtonSend_clicked()
  18. {
  19. udpSocket->writeDatagram(ui->plainTextEdit_sendInfo->toPlainText().toLocal8Bit(),//内容
  20. QHostAddress(ui->lineEditIp->text()),//发送ip
  21. ui->lineEditPort->text().toInt());//发送的地址
  22. }
  23. void Widget::on_pushButtonCLose_clicked()
  24. {
  25. udpSocket->bind(ui->lineEditPort_2->text().toInt());
  26. }
  27. void Widget::readyReadSlot(){
  28. quint64 size = udpSocket->bytesAvailable();//读取发过来的消息大小
  29. QByteArray ba;
  30. ba.resize(size);
  31. QHostAddress address;
  32. quint16 port;
  33. udpSocket->readDatagram(ba.data(),size,&address,&port);
  34. QString str = QString::fromLocal8Bit(ba.data());
  35. ui->textEdit_recvInfo->append(str);
  36. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/981777?site
推荐阅读
相关标签
  

闽ICP备14008679号