0.概述
- 要使用Qt中有关网络编程的API,需要添加
network
模块
1.UDP Socket
1.核心API概览
- 主要的类有两个:
QUdpSocket
和QNetworkDatagram
QUdpSocket
表⽰⼀个UDP的socket⽂件 bind(const QHostAddress&, quint16)
:绑定指定的端口号 receiveDatagram()
:返回QNetworkDatagram
,读取⼀个UDP数据报 writeDatagram(const QNetworkDatagram&)
:发送⼀个UDP数据报 readyRead()
:在收到数据并准备就绪后触发
QNetworkDatagram
表⽰⼀个UDP数据报 QNetworkDatagram(const QByteArray&, const QHostAddress&, quint16)
: - 通过
QByteArray
,⽬标IP地址,⽬标端⼝号构造⼀个UDP数据报 - 通常⽤于发送数据时
data()
:获取数据报内部持有的数据,返回`QByteArraysenderAddress()
:获取数据报中包含的对端的IP地址senderPort()
:获取数据报中包含的对端的端⼝号
2.回显服务器
- ⼀般来说,要先连接信号槽,再绑定端⼝
- 如果顺序反过来,可能会出现端⼝绑定好了之后,请求就过来了,此时还没来得及连接信号槽,那么这个请求就有可能错过了
- 示例:
{socket = new QUdpSocket(this);connect(socket, &QUdpSocket::readyRead, this, &Widget::ProcessRequest);if (!socket->bind(QHostAddress::Any, 2333)){QMessageBox::critical(this, "服务器启动出错", socket->errorString());return;}
}void Widget::ProcessRequest()
{const QNetworkDatagram& req = socket->receiveDatagram();QString request = req.data();const QString& response = Process(request);QNetworkDatagram resp(response.toUtf8(), req.senderAddress(),req.senderPort());socket->writeDatagram(resp);QString log = "[" + req.senderAddress().toString() + ":" + QString::number(req.senderPort()) + "] req: " + request + ", resp: " + response;ui->listWidget->addItem(log);
}QString Widget::Process(const QString &request)
{return request;
}
3.回显客户端
{socket = new QUdpSocket(this);connect(socket, &QUdpSocket::readyRead, this, &Widget::ProcessResponse);
}void Widget::on_pushButton_clicked()
{const QString& text = ui->lineEdit->text();QNetworkDatagram req(text.toUtf8(), QHostAddress(SERVER_IP), SERVER_PORT);socket->writeDatagram(req);ui->listWidget->addItem("客户端说: " + text);ui->lineEdit->setText("");
}
void Widget::ProcessResponse()
{const QNetworkDatagram& resp = socket->receiveDatagram();QString response = resp.data();ui->listWidget->addItem("服务器说: " + response);
}