1.TCP Socket
1.核心API概览
- 核⼼类是两个:QTcpServer和QTcpSocket
- QTcpServer用于监听端口,和获取客户端毗连
- listen(const QHostAddress&, quint16 port):绑定指定的所在和端⼝号,并开始监听
- 成员方法
- 对标原⽣API:bind() 和listen()
- nextPendingConnection():从系统中获取到⼀个已经建⽴好的tcp毗连
- 返回⼀个QTcpSocket,表⽰这个客⼾端的毗连
- 成员方法
- 对标原⽣API:accept()
- newConnection():有新的客⼾端建⽴毗连好之后触发
- QTcpSocket⽤于客⼾端和服务器之间的数据交互
- readAll():读取当前吸取缓冲区中的所有数据,返回QByteArray对象
- write(const QByteArray &):把数据写⼊socket中
- deleteLater():暂时把socket对象标记为⽆效,Qt会在下个事件循环中析构释放该对象
- readyRead():有数据到达并预备就绪时触发
- disconnected():毗连断开时触发
2.回显服务器
- // 构造函数中
- {
- server = new QTcpServer(this);
- // 通过信号槽, 指定如何处理连接.
- connect(server, &QTcpServer::newConnection,
- this, &Widget::ProcessConnection);
-
- // 绑定并监听端口号
- if (!ret = server->listen(QHostAddress::Any, 2333))
- {
- QMessageBox::critical(this, "服务器启动失败!", server->errorString());
- exit(1);
- }
- }
- void Widget::ProcessConnection()
- {
- // 通过 server 拿到一个 socket 对象, 通过这个对象来和客户端进行通信
- QTcpSocket* clientSocket = tcpServer->nextPendingConnection();
-
- QString log = "[" + clientSocket->peerAddress().toString() + ":" +
- QString::number(clientSocket->peerPort()) + "] 客户端上线!";
- ui->listWidget->addItem(log);
- // 通过信号槽, 来处理客户端发来请求的情况
- connect(clientSocket, &QTcpSocket::readyRead, this, [=]() {
- // a) 读取出请求数据,此处 readAll 返回的是 QByteArray, 通过赋值转成 QString
- QString request = clientSocket->readAll();
-
- // b) 根据请求处理响应
- const QString& response = Process(request);
-
- // c) 把响应写回到客户端
- clientSocket->write(response.toUtf8());
-
- // d) 把上述信息记录到日志中.
- QString log = "[" + clientSocket->peerAddress().toString() + ":" +
- QString::number(clientSocket->peerPort()) + "] "
- + " req: " + request + ", resp: " + response;
- ui->listWidget->addItem(log);
- });
- // 通过信号槽, 来处理客户端断开连接的情况.
- connect(clientSocket, &QTcpSocket::disconnected, this, [=]() {
- // a) 把断开连接的信息通过日志显示出来.
- QString log = "[" + clientSocket->peerAddress().toString() + ":" +
- QString::number(clientSocket->peerPort()) + "] 客户端下线!";
- ui->listWidget->addItem(log);
-
- // b) 手动释放 clientSocket. 直接使用 delete 是下策, 使用 deleteLater 更加合适
- clientSocket->deleteLater();
- });
- }
- QString Widget::Process(const QString request)
- {
- return request;
- }
复制代码 3.回显客户端
- // 构造函数中
- {
- socket = new QTcpSocket(this);
-
- // 服务器建立连接,此处是非阻塞的IO通信
- socket->connectToHost("127.0.0.1", 2333);
-
- // 连接信号槽, 处理响应
- connect(socket, &QTcpSocket::readyRead, this, [=]() {
- // a) 读取出响应内容
- QString response = socket->readAll();
-
- // b) 把响应内容显示到界面上.
- ui->listWidget->addItem("服务器说: " + response);
- });
-
- // 等待连接建立的结果. 确认是否连接成功.
- if (!socket->waitForConnected())
- {
- QMessageBox::critical(this, "连接服务器出错", socket->errorString());
- exit(1);
- }
- }
- void Widget::on_pushButton_clicked()
- {
- const QString& text = ui->lineEdit->text();
-
- socket->write(text.toUtf8());
-
- ui->listWidget->addItem("客户端说: " + text);
- ui->lineEdit->setText("");
- }
复制代码 2.HTTP Client
- Qt只提供了Http客户端,并没有提供Http服务端的库
- 关键类主要是三个:QNetworkAccessManager , QNetworkRequest , QNetworkReply
- QNetworkAccessManager提供了HTTP的核⼼操纵
- get(const QNetworkRequest&):发起⼀个HTTP GET哀求,返回QNetworkReply对象
- 本身不是壅闭函数,只负责发出去哀求,不负责等哀求回来
- 收是QNetworkReply负责的,会收到finished信号
- post(const QNetworkRequest&, const QByteArray&):发起⼀个HTTP POST哀求,返回QNetworkReply对象
- QNetworkRequest表⽰⼀个HTTP哀求(不含body),如果必要发送⼀个带有body的哀求(⽐如post),会在QNetworkAccessManager的post()中通过单独的参数来传⼊body
- QNetworkRequest(const QUrl&):通过URL构造⼀个HTTP哀求
- setHeader(QNetworkRequest::KnownHeaders header, const QVariant& value):设置哀求头
- QNetworkRequest::KnownHeaders是⼀个罗列类型,常⽤取值
- ContentTypeHeader:描述body的类型
- ContentLengthHeader:描述body的⻓度
- LocationHeader:⽤于重定向报⽂中指定重定向所在
- CookieHeader:设置cookie
- UserAgentHeader:设置User-Agent
- QNetworkReply表⽰⼀个HTTP相应,这个类同时也是QIODevice的⼦类
- error():获取出错状态
- errorString():获取出错缘故原由的⽂本
- readAll():读取相应body
- header(QNetworkRequest::KnownHeaders header):读取相应指定header的值
- finished():为一个信号,在客⼾端收到完整的相应数据之后触发
- 示例:
- // 构造函数中
- {
- manager = new QNetworkAccessManager(this);
- }
- void Widget::on_pushButton_clicked()
- {
- // 1. 获取到输入框中的 url
- QUrl url(ui->lineEdit->text());
-
- // 2. 构造一个 HTTP 请求对象
- QNetworkRequest request(url);
-
- // 3. 发送请求
- QNetworkReply* response = manager->get(request);
-
- // 4. 通过信号槽, 来处理响应
- connect(response, &QNetworkReply::finished, this, [=]() {
- if (response->error() == QNetworkReply::NoError)
- {
- QString html = response->readAll();
- ui->plainTextEdit->setPlainText(html);
- }
- else
- {
- ui->plainTextEdit->setPlainText(response->errorString());
- }
-
- // 需要对 response 进行手动释放.
- response->deleteLater();
- });
- }
复制代码 3.其他模块
- Qt中还提供了FTP,DNS,SSL等⽹络相关的组件⼯具,有必要可以具体学习,查阅官方文档
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |