客户端
client.pro
#-------------------------------------------------
#
# Project created by QtCreator 2024-07-02T14:11:20
#
#-------------------------------------------------
QT += core gui network #网络通信
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = client
TEMPLATE = app
# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += main.cpp\
widget.cpp
HEADERS += widget.h
FORMS += widget.ui
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QTcpSocket>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
void InitClient();
private slots:
void on_connect_bt_clicked();
void on_send_bt_clicked();
void OnReadData();
private:
Ui::Widget *ui;
QTcpSocket *m_pSocket;
};
#endif // WIDGET_H
main.cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.InitClient();
w.show();
return a.exec();
}
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QDebug> //Qt 提供的输出调试信息的工具。
#include <QHostAddress>
Widget::Widget(QWidget *parent) : //Widget类继承自QWidget
QWidget(parent),
ui(new Ui::Widget) //通过ui对象初始化界面布局
{
ui->setupUi(this);
m_pSocket = NULL; //初始化m_pSocket为NULL
}
Widget::~Widget() //析构函数释放了ui对象。
{
delete ui;
}
void Widget::InitClient() //设置界面初始状态,创建串口对象
{
qDebug() << "Widget::InitClient() enter";
if (NULL == m_pSocket)
{
m_pSocket = new QTcpSocket(this); //QTcpSocket是Qt提供的用于TCP网络通信的类
connect(m_pSocket, SIGNAL(readyRead()), this, SLOT(OnReadData()));
//readyRead()当socket接收到新的数据时发出的信号,SIGNAL()是一个宏,将信号转换为字符串形式。this是信号的发送者。
//当m_pSocket对象接收到数据时,会触发readyRead()信号,然后调用当前类的OnReadData()槽函数来处理这些接收到的数据
}
qDebug() << "Widget::InitClient() exit";
}
void Widget::on_connect_bt_clicked() //当按钮connect_bt被点击时触发
{
qDebug() << "Widget::on_connect_bt_clicked() enter";
QString strIP = ui->ip_edit->text(); //获取用户输入的IP地址
QString strPort = ui->port_edit->text();
qDebug() << strIP << " " << strPort;
if (strIP.length() == 0 || strPort.length() == 0) //检查用户输入的有效性,如果IP或端口号为空,则输出错误信息并返回
{
qDebug() << "input error";
return;
}
if (NULL == m_pSocket) //检查m_pSocket是否为NULL,如果是则输出错误信息并返回
{
qDebug() << "socket error";
return;
}
m_pSocket->connectToHost(QHostAddress("127.0.0.1"), strPort.toShort());
//使用m_pSocket->connectToHost()连接到指定的主机地址(这里是本地地址 "127.0.0.1")和端口号
if (m_pSocket->waitForConnected(3000))
//使用m_pSocket->waitForConnected(3000)等待连接建立,超时时间为3000毫秒(3秒)
{
qDebug() << "connect ok";
}
else
{
qDebug() << "connect error";
}
qDebug() << "Widget::on_connect_bt_clicked() exit";
}
void Widget::on_send_bt_clicked()
{
qDebug() << "Widget::on_send_bt_clicked() enter";
QString strData = ui->send_edit->text();
if (strData.length() == 0)
{
qDebug() << "input error";
return;
}
if (NULL == m_pSocket)
{
qDebug() << "socket error";
return;
}
m_pSocket->write(strData.toStdString().data()); //发送字符串形式的数据到已连接的服务器端
qDebug() << "Widget::on_send_bt_clicked() exit";
}
void Widget::OnReadData()
{
QByteArray arr = m_pSocket->readAll(); //读取所有接收到的数据,并将其存储arr中
qDebug() << arr;
}
widget.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Widget</class>
<widget class="QWidget" name="Widget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>692</width>
<height>468</height>
</rect>
</property>
<property name="windowTitle">
<string>Widget</string>
</property>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>50</x>
<y>60</y>
<width>72</width>
<height>15</height>
</rect>
</property>
<property name="text">
<string>ip</string>
</property>
</widget>
<widget class="QLineEdit" name="ip_edit">
<property name="geometry">
<rect>
<x>100</x>
<y>60</y>
<width>181</width>
<height>21</height>
</rect>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>40</x>
<y>100</y>
<width>72</width>
<height>15</height>
</rect>
</property>
<property name="text">
<string>port</string>
</property>
</widget>
<widget class="QLineEdit" name="port_edit">
<property name="geometry">
<rect>
<x>100</x>
<y>100</y>
<width>181</width>
<height>21</height>
</rect>
</property>
</widget>
<widget class="QPushButton" name="connect_bt">
<property name="geometry">
<rect>
<x>350</x>
<y>90</y>
<width>93</width>
<height>28</height>
</rect>
</property>
<property name="text">
<string>connect</string>
</property>
</widget>
<widget class="QPushButton" name="send_bt">
<property name="geometry">
<rect>
<x>350</x>
<y>150</y>
<width>93</width>
<height>28</height>
</rect>
</property>
<property name="text">
<string>send</string>
</property>
</widget>
<widget class="QLineEdit" name="send_edit">
<property name="geometry">
<rect>
<x>100</x>
<y>160</y>
<width>181</width>
<height>21</height>
</rect>
</property>
</widget>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
服务器
server.pro
#-------------------------------------------------
#
# Project created by QtCreator 2024-07-02T09:20:48
#
#-------------------------------------------------
QT += core gui network
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = server
TEMPLATE = app
# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += main.cpp\
widget.cpp
HEADERS += widget.h
FORMS += widget.ui
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QTcpServer>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
void InitServer();
private slots:
void OnNewConnection();
void OnReadyData();
void on_listen_bt_clicked();
private:
Ui::Widget *ui;
QTcpServer *m_pServer;
};
#endif // WIDGET_H
main.cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.InitServer();
w.show();
return a.exec();
}
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <QHostAddress>
#include <QTcpSocket>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
m_pServer = NULL;
}
Widget::~Widget()
{
delete ui;
}
void Widget::InitServer()
{
qDebug() << "Widget::InitServer() enter";
if (NULL == m_pServer)
{
m_pServer = new QTcpServer(this);
connect(m_pServer, SIGNAL(newConnection()), this, SLOT(OnNewConnection()));
}
qDebug() << "Widget::InitServer() exit";
}
void Widget::OnNewConnection()
{
qDebug() << "new connection";
QTcpSocket *pTmp = m_pServer->nextPendingConnection(); //获取下一个挂起的连接
if (NULL != pTmp)
{
connect(pTmp, SIGNAL(readyRead()), this, SLOT(OnReadyData()));
//当这个客户端socket有数据可读时,就会调用OnReadyData()函数
}
}
void Widget::OnReadyData()
{
qDebug() << "read data";
QTcpSocket *pTmp = (QTcpSocket *)sender(); //获取信号的发送者
if (NULL == pTmp)
{
qDebug() << "socket error";
return;
}
QByteArray arr = pTmp->readAll(); //读取所有接收到的数据
//qDebug() << arr;
QString strData = ui->textEdit->toPlainText(); //将接收到的数据显示在界面中
strData.append("recv : "); //追加数据recv :
strData.append(arr);
strData.append("\n");
ui->textEdit->setText(strData);
pTmp->write(arr); //将接收到的数据原样发送回客户端
}
void Widget::on_listen_bt_clicked()
{
qDebug() << "Widget::on_listen_bt_clicked() enter";
if (NULL == m_pServer)
{
return;
}
QString strIP = ui->ip_edit->text();
QString strPort = ui->port_edit->text();
if (strIP.length() == 0 || strPort.length() == 0)
{
qDebug() << "input error";
return;
}
bool bRet = m_pServer->listen(QHostAddress(strIP), strPort.toShort()); //监听指定的IP地址和端口号
if (bRet == true)
{
qDebug() << "server listen ok";
}
qDebug() << "Widget::on_listen_bt_clicked() enter";
}
widget.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Widget</class>
<widget class="QWidget" name="Widget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>893</width>
<height>629</height>
</rect>
</property>
<property name="windowTitle">
<string>Widget</string>
</property>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>80</x>
<y>60</y>
<width>72</width>
<height>15</height>
</rect>
</property>
<property name="text">
<string>ip</string>
</property>
</widget>
<widget class="QLineEdit" name="ip_edit">
<property name="geometry">
<rect>
<x>140</x>
<y>60</y>
<width>221</width>
<height>21</height>
</rect>
</property>
</widget>
<widget class="QLineEdit" name="port_edit">
<property name="geometry">
<rect>
<x>140</x>
<y>100</y>
<width>221</width>
<height>21</height>
</rect>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>80</x>
<y>100</y>
<width>72</width>
<height>15</height>
</rect>
</property>
<property name="text">
<string>port</string>
</property>
</widget>
<widget class="QPushButton" name="listen_bt">
<property name="geometry">
<rect>
<x>400</x>
<y>100</y>
<width>93</width>
<height>28</height>
</rect>
</property>
<property name="text">
<string>listen</string>
</property>
</widget>
<widget class="QTextEdit" name="textEdit">
<property name="geometry">
<rect>
<x>60</x>
<y>190</y>
<width>761</width>
<height>401</height>
</rect>
</property>
</widget>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
测试