使用QWebSocketServer实现网络数据传输

10 篇文章 0 订阅
1 篇文章 0 订阅

学习记录贴,参考了许多文档,
部分内容参考自 https://www.jianshu.com/p/a9497de4cbff
内容参考自 https://blog.csdn.net/cqchengdan/article/details/97619665#commentBox
内容参考自 https://blog.csdn.net/cqchengdan/article/details/97619483
有问题可以相互请教,这里就是对今天学习内容的总结。

1.模式分类

QWebSocketServer具有安全模式和非安全模式两种类型。体现在初始化类型值的不同
QWebSocketServer::SecureMode 为安全模式。需要配置SSL安全证书,QWebSocketServer::NOSecureMode为非安全模式,直接进行明文传输。

2.非安全模式下QWebsocket实现

2.1 服务器端

1.初始化QWebSocketServer

void DataAnalysisClient::init()
{
    m_WebSocketServer = new QWebSocketServer("Server Name", QWebSocketServer::NoSecureMode, this);
}

2.实现服务器端接口

void DataAnalysisClient::onStartButtonClick()
{
    int i_port = 6000;
    m_WebSocketServer->listen(QHostAddress::Any, i_port);
    m_sendEdit->append(QString("服务启动!"));
}
void DataAnalysisClient::onStopButtonClick()
{
    m_WebSocketServer->close();
    for (int i=0;i<m_clients.size();i++)
    {
        m_clients.at(i)->close();
    }
    m_sendEdit->append(QString("服务停止!"));
}

void DataAnalysisClient::onSendButtonClick()
{
    QString msg = "服务端发送数据!";
    for (int i=0;i<m_clients.size();i++)
    {
        m_clients.at(i)->sendTextMessage(msg);
    }
}
void ACMSLIB::DataAnalysisClient::onNewConnection()
{
    // 读取到下一个等待连接的套接字,套接字需要显式删除
    pSocket = m_WebSocketServer->nextPendingConnection();
    connect(pSocket, SIGNAL(textMessageReceived(QString)), this, SLOT(processTextMessage(QString)));
    connect(pSocket, SIGNAL(disconnected()), this, SLOT(socketDisconnected()));
    QString item = pSocket->peerAddress().toString();
    QString time = current_date_time->currentDateTime().toString("yyyy.MM.dd hh:mm:ss.zzz");
    QString ip = m_WebSocketServer->serverAddress().toString();
    int port = m_WebSocketServer->serverPort();
    QString url = m_WebSocketServer->serverUrl().toString();
    m_sendEdit->append(QString("%1 + "" 新建连接:IP为%2").arg(time).arg(item));
    m_sendEdit->append(QString("IP:%1 + 端口号:%2 + url:%3").arg(ip).arg(port).arg(url));
    m_clients << pSocket;
}

//收到消息并显示
void DataAnalysisClient::processTextMessage(QString message)
{
    QString time = current_date_time->currentDateTime().toString("yyyy.MM.dd hh:mm:ss.zzz");
    QString item = pSocket->peerAddress().toString();
    m_recEdit->append(time + "" + item + "\n" + message);
}

void DataAnalysisClient::socketDisconnected()
{
    QString time = current_date_time->currentDateTime().toString("yyyy.MM.dd hh:mm:ss.zzz");
    QString item = pSocket->peerAddress().toString();
    m_recEdit->append(QString(time + "" + item + "\n" + "失去连接:IP为%1").arg(item));
    m_recEdit->append("\n");
}

2.2 客户端

1.初始化

    // 操作按钮
    connect(m_startBtn, SIGNAL(clicked(bool)), this, SLOT(connectToServer()));
    connect(m_closeBtn, SIGNAL(clicked(bool)), this, SLOT(stopClicked()));
    connect(m_sendBtn, SIGNAL(clicked(bool)), this, SLOT(onSendButtonClicked()));
    // 数据传输
    connect(&m_websocket, SIGNAL(connected()), this, SLOT(onconnected()));
    connect(&m_websocket, SIGNAL(disconnected()), this, SLOT(closeConnection()));
    connect(&m_websocket, SIGNAL(textMessageReceived(QString)), this, SLOT(onTextMessageReceived(QString)));

2.接口实现

void Widget::connectToServer()
{
    QString IP= "***.***.***.***";
    QString prot = "6000";
    QString path = QString("wss://%1:%2").arg(IP).arg(prot);
    QUrl url = QUrl(path);
    m_websocket.open(url);
    // 错误提示
    connect(&m_websocket, SIGNAL(error(QAbstractSocket::SocketError)),
            this, SLOT(readError(QAbstractSocket::SocketError)));
}

void Widget::onTextMessageReceived(const QString &message)
{
    m_recEdit->append("-----------------------------1");
    QString time = current_date_time->currentDateTime().toString("yyyy.MM.dd hh:mm:ss.zzz ddd");
    m_recEdit->append(time + "\n" + message);
}

void Widget::closeConnection()
{
}

void Widget::stopClicked()
{
    m_websocket.close();
}

void Widget::onconnected()
{
    m_recEdit->append("连接成功");
}

void Widget::onSendButtonClicked()
{
    QString msg = "客户端发送数据";
    m_websocket.sendTextMessage(msg);
}

void Widget::onCleanButtonClicked()
{
}

void Widget::readError(QAbstractSocket::SocketError err)
{
    qDebug () << "连接Error!";
}

3.安全模式下QWebsocket实现

3.1 证书准备

QWebsocket安全模式需要对SSL进行验证,QT本身不支持SSL验证,手动下载openSSL

3.2 生成证书

下载安装好后,打开openssl.exe

3.2.1 生成密钥

genrsa -des3 -out server.key 2048

说明:生成rsa私钥,des3算法,2048位强度,server.key是秘钥文件名。
注意:生成私钥,需要提供一个至少4位的密码。

3.2.2 生成CSR(证书签名请求)

req -new -key server.key -out server.csr

说明:需要依次输入国家,地区,城市,组织,组织单位,Common Name和Email。其中Common Name,可以写自己的名字或者域名,如果要支持https,Common Name应该与域名保持一致,否则会引起浏览器警告。

Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:Beijing
Locality Name (eg, city) []:Beijing
Organization Name (eg, company) [Internet Widgits Pty Ltd]:IT
Organizational Unit Name (eg, section) []:IT
Common Name (e.g. server FQDN or YOUR name) []:IT
Email Address []:123456789@qq.com

3.2.3 删除私钥中的密码

rsa -in server.key -out server_no.key

备注:必须操作,不删除的话,在不鉴定客户端证书的情况下也无法连接成功,
在3.2.1创建私钥的过程中,由于必须要指定一个密码。而这个密码会带来一个副作用,那就是在每次Apache启动Web服务器时,都会要求输入密码,这显然非常不方便。要删除私钥中的密码,操作如下:

3.2.4 生成自签名证书

x509 -req -days 365 -in server.csr -signkey server_no.key -out server.crt

由此得到了签名证书server.crt和私钥server_no.key

3.3 设计服务端

在原有使用非安全模式的WebsockeServer服务的基础上添加一些签名证书和验证
1.初始化QWebSocketServer

void DataAnalysisClient::init()
{
    m_WebSocketServer = new QWebSocketServer("Server Name", QWebSocketServer::SecureMode, this);
    //
    QFile certFile(":server.crt");
    QFile keyFile(":server.key");
    if(!certFile.open(QIODevice::ReadOnly)){
        qDebug() << "certfile open failed...";
    }
    if(!keyFile.open(QIODevice::ReadOnly)){
        qDebug() << "keyfile open failed...";
    }
    QSslCertificate cert(&certFile, QSsl::Pem);
    QSslKey key(&keyFile, QSsl::Rsa, QSsl::Pem);
    certFile.close();
    keyFile.close();
    QSslConfiguration conf = m_WebSocketServer->sslConfiguration();
    conf.setPeerVerifyMode(QSslSocket::VerifyNone);
    conf.setLocalCertificate(cert);
    conf.setPrivateKey(key);
    conf.setProtocol(QSsl::TlsV1SslV3);
    m_WebSocketServer->setSslConfiguration(conf);
}

3.4 设计客户端

void Widget::connectToServer()
{
    QString IP= "***.***.***.***";
    QString prot = "6000";
    QString path = QString("wss://%1:%2").arg(IP).arg(prot);
    QUrl url = QUrl(path);
    QSslConfiguration conf = m_websocket.sslConfiguration();
    conf.setPeerVerifyMode(QSslSocket::VerifyNone);
    conf.setProtocol(QSsl::TlsV1SslV3);
    m_websocket.setSslConfiguration(conf);
}

conf.setPeerVerifyMode(QSslSocket::VerifyNone);使用跳过证书验证的方式使用了SSL的安全传输,实现了数据加密功能。

3.5 使用证书验证

修改验证方式为QSslSocket::VerifyPeer,客户端初始化设置为
{
    QString IP= "***.***.***.***";
    QString prot = "6000";
    QString path = QString("wss://%1:%2").arg(IP).arg(prot);
    QUrl url = QUrl(path);
    QSslConfiguration conf = m_websocket.sslConfiguration();
    //conf.setPeerVerifyMode(QSslSocket::VerifyNone);
    conf.setPeerVerifyMode(QSslSocket::VerifyPeer);
    conf.setProtocol(QSsl::TlsV1SslV3);
    m_websocket.setSslConfiguration(conf);
    //解决自签名证书不受信赖问题,VerifyNone不需添加以下代码
    QList<QSslCertificate> certlist = QSslCertificate::fromPath("F:/myself/server.crt");
    QSslError error(QSslError::SelfSignedCertificate, certlist.at(0));
    QList<QSslError> expectedErrors;
    expectedErrors.append(error);
    m_websocket.ignoreSslErrors(expectedErrors);
}

此方法暂时不适用,websocket的报error提示SocketError::SslHandshakeFailedError错误,暂时不知道原因。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
### 回答1: 可以通过以下步骤下载 QWebSocketServer 的例子: 1. 打开一个浏览器,进入 Qt 官方网站(https://www.qt.io/zh-cn/)。 2. 在网站的搜索框中输入 "qwebsocketserver example",然后按下回车键进行搜索。 3. 在搜索结果中,找到与 QWebSocketServer 相关的示例。你可以点击链接进入该示例的页面。 4. 在示例页面上,你可以找到一些有关示例的描述、用法以及代码示例。 5. 通常情况下,在示例页面上你可以找到一个按钮或链接,上面标有 "下载" 或者 "获取示例代码" 等字样。点击该按钮或链接可以下载示例代码的压缩包文件。 6. 点击下载按钮后,浏览器会开始下载压缩包文件。等待文件下载完成。 7. 下载完成后,你可以在浏览器的下载文件夹中找到压缩包文件。解压缩该文件,即可获得示例代码文件夹。 8. 进入示例代码文件夹,你可以找到一个或多个示例文件,其中包含有关使用 QWebSocketServer 的示例代码。 9. 打开示例代码文件,你可以查看和学习如何使用 QWebSocketServer 类来创建 WebSocket 服务器。 请注意,下载示例代码可能需要一定的时间,具体取决于你的网络连接速度。 ### 回答2: 您可以从以下位置下载 QWebSocketServer 示例程序: 1. 首先,您需要访问 Qt 的官方网站:https://www.qt.io/ 2. 在网站的首页上,您会看到一个 "下载" 的选项。点击该选项,然后选择适合您操作系统的版本下载并安装 Qt。注意,QWebSocketServer 是 Qt 的一部分,因此您需要安装 Qt。 3. 安装完成后,打开 Qt Creator,这是一个集成开发环境(IDE),可以在开发 Qt 应用程序时进行使用。 4. 在 Qt Creator 中,选择菜单上的 "文件" -> "新建文件或项目"。 5. 在 "项目" 窗口中,选择 "Qt Console Application" 项目,并点击 "下一步"。 6. 输入项目的名称和存储位置,然后点击 "下一步"。 7. 在 "构建配置" 页面上,选择您所需的构建套件,并点击 "下一步"。 8. 在 "类调度" 页面上,勾选 "需要 QtWebSocket 模块",并点击 "下一步"。 9. 在 "源文件" 页面上,保留默认的选项,并点击 "下一步"。 10. 在 "类" 页面上,保留默认的选项,并点击 "下一步"。 11. 在 "项目配置" 页面上,点击 "下一步"。 12. 在 "文件准备就绪" 页面上,点击 "完成"。 13. 通过 "Ctrl + O" 快捷键或者点击菜单上的 "文件" -> "打开文件或项目",然后选择刚创建的项目文件。 14. 在 Qt Creator 的编辑器中,找到并打开名为 "main.cpp" 的文件。 15. 在 "main.cpp" 文件中,您可以编写使用 QWebSocketServer 的示例代码。例如,您可以创建一个 QWebSocketServer 的实例,启动服务器并监听客户端的连接请求。 16. 点击 "运行" 按钮或按下 "Ctrl + R" 快捷键编译和运行您的示例程序。 通过以上步骤,您就可以下载 QWebSocketServer 示例并开始使用它了。请注意,这只是一个基本的示例,您可以根据您的需求进行更多的自定义和功能实现。 ### 回答3: 你可以从以下几个地方下载QWebSocketServer的例子: 1. Qt官方文档:Qt提供了详细的文档和示例,其中包含了QWebSocketServer使用方法和示例代码。你可以访问Qt官方网站,找到对应版本的文档,然后在文档中搜索QWebSocketServer的例子并下载。 2. GitHub:在GitHub上,有很多开源项目使用QWebSocketServer进行通信,你可以搜索并找到适合你需求的项目,在项目的代码仓库中查找QWebSocketServer的例子,并进行下载和学习。 3. Qt Creator:如果你使用的是Qt Creator作为开发工具,你可以直接在Qt Creator中打开示例浏览器,然后在搜索框中输入QWebSocketServer,就可以找到相关的示例代码和项目。你可以选择相应的示例,然后通过点击“复制到新目录”来将它们复制到你的工程目录,然后进行阅读和学习。 无论你选择哪种方式,使用QWebSocketServer的例子都会帮助你理解和学习如何在Qt中使用QWebSocketServer进行WebSocket通信。你可以通过阅读代码、理解示例中的功能和流程,然后根据自己的需求进行参考和修改。希望以上信息对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值