目录
(1)在.pro文件中添加network,创建QTcpsever对象,
(3)发送与接收数据与服务器类似,但比服务器简单,上图为接收函数,下图为发送函数
成果展示:
1.TCP/IP协议族简单介绍
1.1摘抄自他人对TCP/IP协议族的理解与讲解
该理解来源于;两篇文章:
TCP通讯的定义:TCP (Transmission Control Protocol)和UDP(User Datagram Protocol)协议属于传输层协议。其中TCP提供IP环境下的数据可靠传输,它提供的服务包括数据流传送、可靠性、有效流控、全双工操作和多路复用。通过面向连接、端到端和可靠的数据包发送。
作用:TCP/IP 是用于因特网 (Internet) 的通信协议。 TCP/IP 通信协议是对计算机必须遵守的规则的描述,只有遵守这些规则,计算机之间才能进行通信。
优点: 1.TCP(Transimision Control Protocal)
2.传输控制协议
3.可靠的、面向连接的协议
4.传输效率低
5.UDP(User Datagram Protocal)
6.用户数据报协议
7.不可靠的、无连接的服务
8.传输效率高
TCP指的不是单个具体的协议,而是一个庞大的协议族,是很多通讯协议的大集合。
通讯协议需要遵守ISO(国际标准化组织)制定的七大体系结构,但我们所用的TCP属于传输层的东西,传统上来说TCP/IP被认为是一个四层协议。协议的分层可见下图。这是第一篇文章的大佬做出来的图,个人觉得非常通俗易懂
我们给A朋友发了一则消息“Hello World”,这条消息会先通过相关协议(TCP协议)封装成机代码格式(很不专业的叫法,理解下),通过网络协议(IP)进行再封装,封装成符合网络传输的代码格式,最终由手机的网卡(数据链路层)通过WIFI、运营商网络等(物理层)发送给A朋友。A朋友则会经历一番逆操作,便可以在手机上看到我们发送的“Hello World”。
跟据以上例子,可以简单理解这一通讯过程,本文主要去简单配置、使用TCP/IP协议。
2.用QT进行TCP连接
整体思路:在QT中,它自带了TCP服务,无需我们再多下载其他东西。提到TCP服务,俩设备通讯肯定是绕不开的基础,那么我们可以创建一个简单的对话框,来辅助我们进行调试。
端口号的取值范围一般是0~65535,在计算机中,1024以下的一般都是系统服务的各种端口,这部分端口一般情况下不要去使用。在同一计算机中,端口使用不要重复,也就是每一个连接要对应一个端口号,本代码把端口号设定为9090。
3.服务器的QT制作
3.1服务器的UI界面
以下就是改UI界面对应下文QT代码中的配置名称,制作该UI界面要把握好Widget这个容器以及Layout排列的使用,强烈建议不要吝啬对Widget的使用,他们能使你的界面美观且会适应外界的缩放
3.2服务器的基本配置
(1)在.pro文件中添加network,创建QTcpsever对象,
获取本机IP地址(可以没有),也可以不获取,自己设置,如设置为127.0.0.1等等,
(2)对指定端口进行监听,
使用server->listen(QHostAddress::Any,port); //打开TCP服务器端的监听
(3)如果监听后指定端口有信号,则创建socket连接,
并把所链接的客户端数据存进cbxConnection和tcpClient链表中。
(4)如果监听到有端口断开,则遍历所有端口,
进行检测,后删掉所断开的端口数据。
(5)数据发送和接收,通过链表进行遍历数据发送。
进行遍历检测,如果发过来的数据不为空,则显示在Edit框中
(6)附上服务器端源码
.pro文件中就添加了一句,这里就不展示了。
mainwindow.cpp文件源码:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "QLabel"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
this->setWindowTitle("TcpClient");
m_socket = new QTcpSocket(this);
ui->COM_lineEdit->setText("9090");
//与服务器连接成功
connect(m_socket,&QTcpSocket::connected,this,[=](){ //当成功连接时会触发这个信号
ui->COM_record->append("-----客户端完成与服务器的连接-----");
});
//接收数据
connect(m_socket,&QTcpSocket::readyRead,this,[=](){ //当有新数据时,会触发这个信号
QByteArray buf = m_socket->readAll();
ui->COM_record->append("服务器:" + buf); //将数据展示出来
});
//断开连接
connect(m_socket,&QTcpSocket::disconnected,this,[=](){ //当与服务器断开时出发这个信号
ui->COM_record->append("-----与服务器断开连接-----");
ui->IP_pushButton->setEnabled(false);
ui->COM_pushButton->setEnabled(true);
});
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_COM_pushButton_clicked()
{
QString ip = ui->IP_lineEdit->text();
unsigned short port = ui->COM_lineEdit->text().toUShort(); //转成16位的无符号数
//连接服务器
m_socket->connectToHost(QHostAddress(ip),port);
ui->COM_pushButton->setDisabled(true); //将监听按钮设置为禁用
ui->IP_pushButton->setDisabled(false);
}
void MainWindow::on_IP_pushButton_clicked()
{
m_socket->close();
ui->COM_pushButton->setEnabled(true);
ui->IP_pushButton->setEnabled(false);
}
void MainWindow::on_sendMassage_pushButton_clicked()
{
QString message = ui->sendMessage_record->toPlainText();//获取将要发送的文本
QByteArray sendMessage = message.toUtf8();//将文本数据转换为UTF-8
m_socket->write(sendMessage);//发送数据
ui->COM_record->append("服务器:" + sendMessage);//将发送数据记录下来
ui->sendMessage_record->clear();//将发送数据框清空
}
void MainWindow::on_pushButton_clicked()
{
ui->COM_record->clear();
}
4.客户端的QT制作
4.1客户端的UI界面
4.2客户端的基本配置
(1)创建的pro文件与头函数可以与服务器函数相同。
、
(2)直接获取socket的connected信号
(3)发送与接收数据与服务器类似,但比服务器简单,上图为接收函数,下图为发送函数
(4)附上客户端端源码:
mainwindow.cpp文件源码:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "QLabel"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
this->setWindowTitle("TcpClient");
m_socket = new QTcpSocket(this);
ui->COM_lineEdit->setText("9090");
//与服务器连接成功
connect(m_socket,&QTcpSocket::connected,this,[=](){ //当成功连接时会触发这个信号
ui->COM_record->append("-----客户端完成与服务器的连接-----");
});
//接收数据
connect(m_socket,&QTcpSocket::readyRead,this,[=](){ //当有新数据时,会触发这个信号
QByteArray buf = m_socket->readAll();
ui->COM_record->append("服务器:" + buf); //将数据展示出来
});
//断开连接
connect(m_socket,&QTcpSocket::disconnected,this,[=](){ //当与服务器断开时出发这个信号
ui->COM_record->append("-----与服务器断开连接-----");
ui->IP_pushButton->setEnabled(false);
ui->COM_pushButton->setEnabled(true);
});
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_COM_pushButton_clicked()
{
QString ip = ui->IP_lineEdit->text();
unsigned short port = ui->COM_lineEdit->text().toUShort(); //转成16位的无符号数
//连接服务器
m_socket->connectToHost(QHostAddress(ip),port);
ui->COM_pushButton->setDisabled(true); //将监听按钮设置为禁用
ui->IP_pushButton->setDisabled(false);
}
void MainWindow::on_IP_pushButton_clicked()
{
m_socket->close();
ui->COM_pushButton->setEnabled(true);
ui->IP_pushButton->setEnabled(false);
}
void MainWindow::on_sendMassage_pushButton_clicked()
{
QString message = ui->sendMessage_record->toPlainText();//获取将要发送的文本
QByteArray sendMessage = message.toUtf8();//将文本数据转换为UTF-8
m_socket->write(sendMessage);//发送数据
ui->COM_record->append("服务器:" + sendMessage);//将发送数据记录下来
ui->sendMessage_record->clear();//将发送数据框清空
}
void MainWindow::on_pushButton_clicked()
{
ui->COM_record->clear();
}
5.总结以及代码
因为临近考试,这篇文章的详细部分之后再补充吧,总的来说,对于嵌入式方向,用QT去编写服务器与客户端是必须掌握的能力,希望这篇文章对大家有所帮助!!!
以下是工程源代码:
链接:https://pan.baidu.com/s/16bA7lmTaYACEMSCAVU_0Eg
提取码:xlpr