此为QT编程的第十八谈!关注我,带你快速学习QT编程的学习路线!
每一篇的技术点都是很很重要!很重要!很重要!但不冗余!
我们通常采取总-分-总和生活化的讲解方式来阐述一个知识点!
码农不易,各位学者学到东西请点赞支持支持!
开始部分:
总:此次实战主要是实现一个客户端,一个服务端,来了解TCP通信的过程。
分:
一、客户端的实现
1.老规矩,创建一个QMainWindow项目
2.先在.ui文件布局好
3.在.h引入相关头文件
4.在.h文件声明一个客户端专属的socket,相当于电话机,用来通信服务器
5.再声明closeEvent事件,相当于电话机挂号,断开服务器的通信
6.再声明连接函数、断开连接函数、发送消息槽函数的基本功能,再添加一个获取ip地址函数
7.声明完成,就在.cpp进行实现了,首先创建专属的电话机,客户端socket
8.首先实现QComboBox获取本机ip地址的一个功能,就要先实现getlocalip()功能
9.将获取到的ip地址存入QComboBox里面
10.实现连接函数、断开连接函数、发送消息槽函数的基本功能
11.连接信号与槽,当socket连接和断开连接和收到数据的时候触发这些槽函数
12.三个按钮的槽函数实现
13.再将关闭事件实现
14.基础的功能已经完美实现了!发送消息,接收消息,连接,断开连接四个主要的功能,通关qt的信号与槽机制完美实现!
15.需要通过与服务器进行连接检测,检测成功!
二、服务端的实现
1.创建QMainWindow一个项目
2.在.ui布局添加相关控件
3.在.pro添加配置,在.h文件添加相关头文件
4..h文件声明一个QTcpServer对象和一个QTcpSocket对象
5.声明函数和槽函数还有关闭事件
6.先实现四个服务器的基础功能,客户端连接,客户端断开,读取数据,发送数据功能
7.创建一个新连接的槽函数,当有新连接的时候就调用
8.再实现剩下的按钮槽函数
9.实现关闭事件
10.实现最主要的自定义函数来获取本地ip地址
11.在构造函数创建对象和连接槽
12.实现效果如下:
总:无论是客户端还是服务端,实现的基础功能都是四个,建立连接,断开连接,发送数据,接收数据。
客户端的参考源码:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//客户端专属socket
tcpclient=new QTcpSocket(this);
QString strip=getlocalip();
ui->comboBox_ip->addItem(strip);
connect(tcpclient,SIGNAL(connected()),this,SLOT(connectfunc()));
connect(tcpclient,SIGNAL(disconnected()),this,SLOT(disconnectfunc()));
connect(tcpclient,SIGNAL(readyRead()),this,SLOT(socketreaddata()));
}
MainWindow::~MainWindow()
{
delete ui;
}
QString MainWindow::getlocalip()//获取本机ip地址
{
QString hostname=QHostInfo::localHostName();//获取本地主机名
QHostInfo hostinfo=QHostInfo::fromName(hostname);//通过主机名获取主机信息
QString localip="";
QList<QHostAddress>addlist=hostinfo.addresses();//获取本机的所有ip地址
if(!addlist.isEmpty())
{
for(int i=0;i<addlist.count();i++)
{
QHostAddress ahost=addlist.at(i);
if(QAbstractSocket::IPv4Protocol==ahost.protocol())
{
localip=ahost.toString();
break;
}
}
}
return localip;
}
void MainWindow::connectfunc()//连接
{
ui->plainTextEdit_Show->appendPlainText("*********已经连接到服务器端**********");
ui->plainTextEdit_Show->appendPlainText("************peer address:"+tcpclient->peerAddress().toString());
ui->plainTextEdit_Show->appendPlainText("************peer port:"+QString::number(tcpclient->peerPort()));
ui->pushButton_connect->setEnabled(false);
ui->pushButton_quit->setEnabled(true);
}
void MainWindow::disconnectfunc()//断开连接
{
ui->plainTextEdit_Show->appendPlainText("************已断开服务端的连接************");
ui->pushButton_connect->setEnabled(true);
ui->pushButton_quit->setEnabled(false);
}
void MainWindow::socketreaddata()//读取信息
{
while(tcpclient->canReadLine())//检查是否有完整的行数据
ui->plainTextEdit_Show->appendPlainText("输入:"+tcpclient->readLine());
}
void MainWindow::on_pushButton_connect_clicked()//连接服务
{
QString addr=ui->comboBox_ip->currentText();
quint16 port=ui->spinBox_port->value();
tcpclient->connectToHost(addr,port);
}
void MainWindow::on_pushButton_quit_clicked()//停止服务
{
if(tcpclient->state()==QAbstractSocket::ConnectedState)
tcpclient->disconnectFromHost();
}
void MainWindow::on_pushButton_send_clicked()//发送消息
{
QString strmsg=ui->lineEdit_Msg->text();
ui->plainTextEdit_Show->appendPlainText("输出:"+strmsg);
ui->lineEdit_Msg->clear();
QByteArray str=strmsg.toUtf8();
str.append("\n");
tcpclient->write(str);//发送数据给服务端
}
void MainWindow::closeEvent(QCloseEvent *event)
{
if(tcpclient->state()==QAbstractSocket::ConnectedState)
{
tcpclient->disconnectFromHost();//断开与服务器的连接
}
event->accept();
}
服务端的参考源码:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
QString strip=GetLocalIpAddress();
ui->comboBoxIp->addItem(strip);
tcpserver=new QTcpServer(this);
connect(tcpserver,SIGNAL(newConnection()),this,SLOT(newconnection()));//存放了基础功能的信号与槽
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_Start_clicked()//开始服务
{
QString ip=ui->comboBoxIp->currentText();
quint16 port=ui->spinBoxPort->value();
QHostAddress address(ip);
tcpserver->listen(address,port);
ui->plainTextEdit_DispMsg->appendPlainText("$$$$$$$$$$开始监听$$$$$$$$$$");
ui->plainTextEdit_DispMsg->appendPlainText("$$$$$$$$$$服务器地址$$$$$$$$$$:"+
tcpserver->serverAddress().toString());
ui->plainTextEdit_DispMsg->appendPlainText("$$$$$$$$$$服务器端口$$$$$$$$$$:"+
QString::number(tcpserver->serverPort()));
ui->pushButton_Start->setEnabled(false);
ui->pushButton_Stop->setEnabled(true);
}
void MainWindow::on_pushButton_Stop_clicked()//停止服务
{
if(tcpserver->isListening())
{
tcpserver->close();
tcpsocket->disconnect(); // 加上该关闭套接,服务器停止后,再也无法收到客户端的消息
ui->pushButton_Start->setEnabled(true);
ui->pushButton_Stop->setEnabled(false);
}
}
void MainWindow::on_pushButton_Send_clicked()//发送数据
{
QString strmsg=ui->lineEdit_InputMsg->text();
ui->plainTextEdit_DispMsg->appendPlainText("[out]:"+strmsg);
ui->lineEdit_InputMsg->clear();
QByteArray str=strmsg.toUtf8();
str.append("\n");
tcpsocket->write(str);
}
QString MainWindow::GetLocalIpAddress() // 获取本机的IP地址
{
QString hostname=QHostInfo::localHostName();
QHostInfo hostinfo=QHostInfo::fromName(hostname);
QString localip="";
QList<QHostAddress> addresslist=hostinfo.addresses();
if(!addresslist.isEmpty())
{
for (int i=0;i<addresslist.count();i++)
{
QHostAddress addrhost=addresslist.at(i);
if(QAbstractSocket::IPv4Protocol==addrhost.protocol())
{
localip=addrhost.toString();
break;
}
}
}
return localip;
}
void MainWindow::clientconnect()
{
// 客户端连接
ui->plainTextEdit_DispMsg->appendPlainText("**********客户端socket连接**********");
ui->plainTextEdit_DispMsg->appendPlainText("**********peer address:"+
tcpsocket->peerAddress().toString());
ui->plainTextEdit_DispMsg->appendPlainText("**********peer port:"+
QString::number(tcpsocket->peerPort()));
}
void MainWindow::clientdisconnect()
{
// 客户端断开连接
ui->plainTextEdit_DispMsg->appendPlainText("**********客户端socket断开连接**********");
tcpsocket->deleteLater();
}
void MainWindow::socketreaddata()
{
// 读取数据
while(tcpsocket->canReadLine())
ui->plainTextEdit_DispMsg->appendPlainText("[in]"+tcpsocket->readLine());
}
void MainWindow::newconnection()//存放各种信号与槽
{
tcpsocket=tcpserver->nextPendingConnection();
connect(tcpsocket,SIGNAL(connected()),this,SLOT(clientconnect()));
clientconnect();
connect(tcpsocket,SIGNAL(disconnected()),this,SLOT(clientdisconnect()));
connect(tcpsocket,SIGNAL(readyRead()),this,SLOT(socketreaddata()));
}
void MainWindow::closeEvent(QCloseEvent *event)
{
if(tcpserver->isListening())
tcpserver->close();
event->accept();
}
学习链接:此https://xxetb.xetslk.com/s/3Kif2D