目录
需要添加网络模块
QT += core gui network
一、TCP
1、QTcpServer
1.1概念
①QTcpServer 是 Qt 中的一个网络模块,它提供了基于 TCP 协议的服务器端编程接口,可以实现服务器端的网络通信。通过 QTcpServer,我们可以很方便地创建一个 TCP 服务器,接受来自客户端的连接请求,并与客户端进行数据通信。
②在使用 QTcpServer 时,我们需要实现它的槽函数来处理客户端连接、数据读取、客户端断开等事件。QTcpServer 提供了一些信号,如 newConnection()、disconnected() 和 readyRead() 等,用于通知我们这些事件的发生。我们可以通过连接这些信号来实现服务器的各种功能,如接受客户端连接、读取客户端数据、向客户端发送数据等。
③除了 QTcpServer,Qt 还提供了其他一些网络模块,如 QUdpSocket 和 QNetworkAccessManager 等,它们分别对应于基于 UDP 协议的数据通信和 HTTP 协议的网络通信。
1.2 添加头文件
#include <QTcpServer>
#include <QTcpSocket>
1.3 主要代码
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
this->setWindowTitle("TcpServer");
tcpServer = new QTcpServer(this);
connect(tcpServer,SIGNAL(newConnection()),this,SLOT(mNewConnetion()));
}
Widget::~Widget()
{
delete ui;
}
void Widget::mNewConnetion()
{
//与客户端链接 从连接队列中获取下一个连接对象
QTcpSocket *tmpTcpSocket=tcpServer->nextPendingConnection();
//打印客户端的ip 端口等信息
QString ipAddr=tmpTcpSocket->peerAddress().toString(); //客户端ip地址
quint16 port=tmpTcpSocket->peerPort(); //客户端端口号
ui->textBrowser->append("客户端的ip:" + ipAddr);
ui->textBrowser->append("客户端的port:" + QString::number(port));
connect(tmpTcpSocket,SIGNAL(readyRead()),this,SLOT(receiveMessages()));
connect(tmpTcpSocket,SIGNAL(stateChanged(QAbstractSocket::SocketState)),
this,SLOT(mStateChanged(QAbstractSocket::SocketState)));
}
void Widget::receiveMessages()
{
QTcpSocket *tmpTcpSocket=(QTcpSocket*)sender();
ui->textBrowser->append("客户端: "+tmpTcpSocket->readAll());
}
void Widget::mStateChanged(QAbstractSocket::SocketState state)
{
QTcpSocket *tmpTcpSocket=(QTcpSocket*)sender();
switch(state) {
case QAbstractSocket::UnconnectedState://表示未连接状态,即还没有尝试建立连接
ui->textBrowser->append("客户端断开连接");
//delete tmpTcpSocket;//不能在这样删除,可能其他地方还在用tmpTcpSocket而导致程序异常
tmpTcpSocket->deleteLater();//延时删除,其他地方也没用之后再释放资源
break;
case QAbstractSocket::HostLookupState: break;//表示正在进行主机名解析的状态,即正在将主机名转换为IP地址
case QAbstractSocket::ConnectingState: break;//表示正在尝试连接的状态
case QAbstractSocket::ConnectedState: break;//表示已连接的状态
case QAbstractSocket::BoundState: break;//表示已绑定到一个本地地址的状态,等待连接请求
case QAbstractSocket::ListeningState: break;//表示正在监听连接请求的状态
case QAbstractSocket::ClosingState: break;//表示正在关闭连接的状态
}
}
void Widget::on_pushButton_3_clicked()
{
QList <QTcpSocket *> socketList = tcpServer->findChildren<QTcpSocket *>();
qDebug()<<"tcpSocket数量:"<<socketList.count()<<endl;
if (socketList. count() == 0)
{
ui->textBrowser-> append("当前没有客户端连接,请先与客户端连接! ");
return;
}
/*foreach(QTcpSocket *tmpTcpSocket,socketList){
//服务端向每个客户端发送消息
tmpTcpSocket->write(ui->lineEdit->text().toUtf8());
}*/
for(auto e:socketList)
{
e->write(ui->lineEdit->text().toUtf8());
}
ui-> textBrowser->append("服务端已发送: " + ui->lineEdit->text());
}
void Widget::on_pushButton_clicked()
{
ui->textBrowser->append("服务端:绑定的ip地址和端口: 192.168.1.59, 9999") ;
//绑定ip和端口
tcpServer->listen(QHostAddress("192.168.230.130"),9999);
}
void Widget::on_pushButton_4_clicked()
{
ui->textBrowser->clear();
}
void Widget::on_pushButton_2_clicked()
{
tcpServer->close();
}
2、TCPClient
1、实现步骤
- 创建QTcpSocket对象,该对象用于建立TCP连接并进行通信。
- 连接到服务器
- 监听连接的信号,以确定是否成功建立了连接
- 实现连接成功时的槽函数
- 实现从服务器接收数据的槽函数
- 发送数据给服务器
- 断开连接
2、主要代码
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
this->setWindowTitle("TcpClient");
ui->pushButton_2->setEnabled(false);
tcpSocket = new QTcpSocket(this);
connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(reciveMessages()));
connect(tcpSocket,SIGNAL(stateChanged(QAbstractSocket::SocketState)),this,SLOT(mStateChanged(QAbstractSocket::SocketState)));
}
Widget::~Widget()
{
delete ui;
}
void Widget::reciveMessages()
{
ui->textBrowser->append("服务端: " + tcpSocket->readAll());
}
void Widget::mStateChanged(QAbstractSocket::SocketState state)
{
switch (state) {
case QAbstractSocket::UnconnectedState:
ui->textBrowser->append("与服务端断开连接");
ui->pushButton->setEnabled(true);
ui->pushButton_2->setEnabled(false);
break;
case QAbstractSocket::ConnectedState:
ui->textBrowser-> append("已连接服务端");
ui->pushButton->setEnabled(false);
ui->pushButton_2->setEnabled(true);
break;
default:
break;
}
}
void Widget::on_pushButton_3_clicked()
{
//发送消息
if(tcpSocket->state()==QAbstractSocket::ConnectedState){
tcpSocket->write(ui->lineEdit->text().toUtf8());
ui-> textBrowser->append("客户端已发送: " + ui->lineEdit->text()) ;
}
else
ui->textBrowser->append("请先与服务端连接!");
}
void Widget::on_pushButton_clicked()
{
//连接服务端,指定服务端ip 和 port
tcpSocket->connectToHost(QHostAddress("192.168.230.130"),9999);
ui->textBrowser->append("客户端:连接的ip地址和端口: 192.168.1.59, 9999");
}
void Widget::on_pushButton_2_clicked()
{
//断开连接
tcpSocket->disconnectFromHost();
}
void Widget::on_pushButton_4_clicked()
{
ui->textBrowser->clear();
}
二、UDP
1、实现步骤
①创建一个 QUdpSocket 对象,可以使用 QUdpSocket::QUdpSocket() 构造函数来创建。
②使用 QUdpSocket::bind() 函数将 QUdpSocket 对象绑定到指定的端口上,这样就可以接收到客户端发送的数据了。
③在 QUdpSocket 对象的 readyRead() 信号中,使用 QUdpSocket::readDatagram() 函数读取客户端发送的数据。
④对接收到的数据进行处理,可以使用 QUdpSocket::writeDatagram() 函数将处理结果返回给客户端。
⑤创建一个 UDP 客户端,也是使用 QUdpSocket 对象来实现。在客户端中使用 QUdpSocket::writeDatagram() 函数发送数据到服务器。
⑥在 UDP 通信完成后,需要关闭服务器和客户端,可以使用 QUdpSocket::close() 函数来关闭 QUdpSocket 对象。
2、 涉及头文件
#include <QTcpSocket>
#include <QHostAddress>
3、 主要实现代码
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
this->setWindowTitle("TcpClient");
ui->pushButton_2->setEnabled(false);
tcpSocket = new QTcpSocket(this);
connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(reciveMessages()));
connect(tcpSocket,SIGNAL(stateChanged(QAbstractSocket::SocketState)),this,SLOT(mStateChanged(QAbstractSocket::SocketState)));
}
Widget::~Widget()
{
delete ui;
}
void Widget::reciveMessages()
{
ui->textBrowser->append("服务端: " + tcpSocket->readAll());
}
void Widget::mStateChanged(QAbstractSocket::SocketState state)
{
switch (state) {
case QAbstractSocket::UnconnectedState:
ui->textBrowser->append("与服务端断开连接");
ui->pushButton->setEnabled(true);
ui->pushButton_2->setEnabled(false);
break;
case QAbstractSocket::ConnectedState:
ui->textBrowser-> append("已连接服务端");
ui->pushButton->setEnabled(false);
ui->pushButton_2->setEnabled(true);
break;
default:
break;
}
}
void Widget::on_pushButton_3_clicked()
{
//发送消息
if(tcpSocket->state()==QAbstractSocket::ConnectedState){
tcpSocket->write(ui->lineEdit->text().toUtf8());
ui-> textBrowser->append("客户端已发送: " + ui->lineEdit->text()) ;
}
else
ui->textBrowser->append("请先与服务端连接!");
}
void Widget::on_pushButton_clicked()
{
//连接服务端,指定服务端ip 和 port
tcpSocket->connectToHost(QHostAddress("192.168.230.130"),9999);
ui->textBrowser->append("客户端:连接的ip地址和端口: 192.168.1.59, 9999");
}
void Widget::on_pushButton_2_clicked()
{
//断开连接
tcpSocket->disconnectFromHost();
}
void Widget::on_pushButton_4_clicked()
{
ui->textBrowser->clear();
}