网络通信(传输层协议:TCP/IP ,UDP):
Socket是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。一个套接字就是网络上进程通信的一端,提供了应用层进程利用网络协议交换数据的机制。
网络协议:一台电脑的数据怎么传递给另一台电脑,是由网络协议来规定的
端口号:类似于办事窗口,是在计算机网络中用于区分不同服务或应用程序的一种数字标识。每个正在运行的程序或服务都会监听或绑定到一个或多个端口号上,以便接收来自网络的数据包。
客户端软件从端口号发给服务器,服务器内的服务器软件会识别是哪个软件发出的,调用软件对应的处理
Socket主要分为以下几种类型:
-
流式套接字(TCP Socket):
- 提供可靠的、面向连接的通信。
- 数据按顺序传输,不丢失。
- 建立连接时需要三次握手,断开时需要四次挥手。
- 适用场景:文件传输、Web服务等。
-
数据报套接字(UDP Socket):
- 提供快速但不可靠的通信。
- 无需建立连接,直接发送数据。
- 数据可能丢失,适合对速度要求高的场景。
- 适用场景:实时音视频、在线游戏等。
TCP:面向连接的流式协议,数据安全,3次握手4次挥手,双向连接,双向断开,有数据校验机制
TCP的通信流程:
UDP:面向无连接报式协议,数据不安全,不需要连接,报文要是丢包就全丢了
UDP的通信流程:
-
QTcpServer(监听套接字)和QTcpSocket(通讯套接字)
在项目的配置文件内添加
QT += core gui network
TCP的通信服务器端:
.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QLabel>
#include <QMainWindow>
#include <QTcpServer> //添加的头文件
#include <QTcpSocket>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
private:
Ui::MainWindow *ui;
///服务器
QTcpServer *tcpServer;
///监听端口
QTcpSocket *tcpSocket;
QLabel *Status;
};
#endif // MAINWINDOW_H
.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
///1.创建服务器
tcpServer=new QTcpServer(this);
///设置端口号
ui->lineEdit_port->setText("8899");
connect(tcpServer,&QTcpServer::newConnection,this,[=](){
///3.建立连接,获取监听对象
tcpSocket=tcpServer->nextPendingConnection();
//连接成功设置状态图片并缩放图片大小(已连接)
Status->setPixmap(QPixmap(":/new/prefix1/img/a2.png").scaled(20,20));
///4.检测是否可以接收数据
connect(tcpSocket,&QTcpSocket::readyRead,this,[=](){
QByteArray data=tcpSocket->readAll();
ui->textBrowser->append("客户端说:"+data);
});
///6.检测断开连接
connect(tcpSocket,&QTcpSocket::disconnected,this,[=](){
///关闭套接字
tcpSocket->close();
///释放
tcpSocket->deleteLater();
//设置状态图片并缩放图片大小(未连接)
Status->setPixmap(QPixmap(":/new/prefix1/img/a1.png").scaled(20,20));
});
});
//设置状态栏
Status=new QLabel;
//设置状态图片并缩放图片大小(未连接)
Status->setPixmap(QPixmap(":/new/prefix1/img/a1.png").scaled(20,20));
ui->statusbar->addWidget(new QLabel("连接状态:"));
ui->statusbar->addWidget(Status);
}
MainWindow::~MainWindow()
{
delete ui;
}
///点击启动监听
void MainWindow::on_pushButton_clicked()
{
///2.设置监听
unsigned short port=ui->lineEdit_port->text().toUShort();
tcpServer->listen(QHostAddress::Any,port);
///启动监听按钮不可选
ui->pushButton->setDisabled(true);
}
///发送按钮按下
void MainWindow::on_pushButton_2_clicked()
{
QString str= ui->textBrowser_2->toPlainText();
///5.发送数据
tcpSocket->write(str.toUtf8());
ui->textBrowser->append("服务器说:"+str);
}
TCP的通信客户端:
.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QLabel>
#include <QMainWindow>
#include <QTcpSocket>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_pushButton_2_clicked();
void on_pushButton_connect_clicked();
void on_pushButton_disConnect_clicked();
private:
Ui::MainWindow *ui;
///监听端口
QTcpSocket *tcpSocket;
QLabel *Status;
};
#endif // MAINWINDOW_H
.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QHostAddress>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
///1.创建客户端
tcpSocket=new QTcpSocket(this);
///设置端口号
ui->lineEdit_port->setText("8899");
///设置ip(本地IP)
ui->lineEdit_Ip->setText("127.0.0.1");
///断开连接按钮不显示
ui->pushButton_disConnect->setDisabled(true);
///3.连接到服务器
connect(tcpSocket,&QTcpSocket::connected,this,[=](){
//设置状态图片并缩放图片大小(已连接)
Status->setPixmap(QPixmap(":/new/prefix1/img/a2.png").scaled(20,20));
ui->textBrowser->append("已连接到服务器");
ui->pushButton_disConnect->setDisabled(false);
ui->pushButton_connect->setDisabled(true);
});
///5.接收数据
connect(tcpSocket,&QTcpSocket::readyRead,this,[=](){
QByteArray data=tcpSocket->readAll();
ui->textBrowser->append("服务器说:"+data);
});
///6.断开连接
connect(tcpSocket,&QTcpSocket::disconnected,this,&MainWindow::on_pushButton_disConnect_clicked);
//设置状态栏
Status=new QLabel;
//设置状态图片并缩放图片大小(未连接)
Status->setPixmap(QPixmap(":/new/prefix1/img/a1.png").scaled(20,20));
ui->statusbar->addWidget(new QLabel("连接状态:"));
ui->statusbar->addWidget(Status);
}
MainWindow::~MainWindow()
{
delete ui;
}
///发送按钮按下
void MainWindow::on_pushButton_2_clicked()
{
QString str= ui->textBrowser_2->toPlainText();
///4.发送数据
tcpSocket->write(str.toUtf8());
ui->textBrowser->append("客户端说:"+str);
}
void MainWindow::on_pushButton_connect_clicked()
{
///2.连接服务器
QString ip=ui->lineEdit_Ip->text();
unsigned short port=ui->lineEdit_port->text().toUShort();
tcpSocket->connectToHost(QHostAddress(ip),port);
}
void MainWindow::on_pushButton_disConnect_clicked()
{
///关闭套接字
tcpSocket->close();
//设置状态图片并缩放图片大小(未连接)
Status->setPixmap(QPixmap(":/new/prefix1/img/a1.png").scaled(20,20));
ui->textBrowser->append("已断开服务器");
ui->pushButton_disConnect->setDisabled(true);
ui->pushButton_connect->setDisabled(false);
}