C++实现websocket服务器握手协议(使用Qt)

2023-05-16

前提:笔者在开发server程序时,要求websocket与server连接

websocket的机制是在第一次连接时进行握手协议,协议通过,才可以进行正常的通信,否则websocket就会断开连接;

下面就是websocket第一次发送的握手包:

GET / HTTP/1.1\r\n
Host: 192.168.5.24:17913\r\n
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0\r\n
Accept: */*\r\n
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2\r\n
Accept-Encoding: gzip, deflate\r\n
Sec-WebSocket-Version: 13\r\n
Origin: http://127.0.0.1:8848\r\n
Sec-WebSocket-Extensions: permessage-deflate\r\n
Sec-WebSocket-Key: tepG0DQZtEJ7MLbw7kbewA==\r\n
Connection: keep-alive, Upgrade\r\n
Pragma: no-cache\r\nCache-Control: no-cache\r\n
Upgrade: websocket\r\n\r\n

那需要对websocket发送来的第一个数据进行处理(判断是否是第一个包,可以通过开头GET来进行判断,可能不是非常严谨),获取Sec-WebSocket-Key的值(也就是上面的ikLk+bBgZDQRPTOBAzGsBg==),然后对此进行解析。

解析的方法是在key上加上固定字符串“258EAFA5-E914-47DA-95CA-C5AB0DC85B11”,再进行sha1解码及base64编码,然后打包发送给websocket客户端。

返回的握手包如下:

HTTP/1.1 101 Switching Protocols\r\n
Connection: upgrade\r\n
Sec-WebSocket-Accept: mhW8gChbFWgUKJxpzcbPlcwJxcw=\r\n
Upgrade: websocket\r\n\r\n

代码如下:

void rcvReadData()
{
    QByteArray data_ = this->readAll();//socket接收数据
    if(!_firstConnect)//第一个包
    {
        _firstConnect = true;
        QString qstr_ = data_;//包数据转化成QString
        QString key_ = "";
        key_ = getKey(qstr_);
        if(key_ == "-1")
        {
            //自定义处理
        }
        else if(key_ == "-2")
        {
            //自定义处理
        }
        else
        {
            //处理key
            char request[1024] = "";  //请求信息
            respondHandshake(request,key_.toStdString());
            QByteArray array_(request);
            write(array_);//发送数据给websocket客户端
        }
    }
    else
    {
        //接下来包在此不做处理,需要涉及到websocket协议的解包
    }
}

/**
*获取Sec-WebSocket-Key的值,QT实现
*/
QString getKey(QString qstr)
{
    int i = qstr.indexOf("GET");
    if(i < 0)
    {
        return "-1";
    }
    int j = qstr.indexOf("Sec-WebSocket-Key");
    if(j < 0)
    {
        return "-2";
    }
    QString key = qstr.mid(j + 19, 24);
    return key;
}

/**
*获取Sec-WebSocket-Key的值,C++实现
*/
string getKey(string str)
{
    int i = str.find("GET");
    if(i < 0)
    {
        return "-1";
    }
    int j = str.find("Sec-WebSocket-Key");
    if(j < 0)
    {
        return "-2";
    }
    string key = str.substr(j + 19, 24);
    return key;
}

void respondHandshake(char *request, string clientkey)
{
    strcat(request, "HTTP/1.1 101 Switching Protocols\r\n");
    strcat(request, "Connection: upgrade\r\n");
    strcat(request, "Sec-WebSocket-Accept: ");
    string server_key = clientkey;
    server_key += "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";

    SHA1  sha;
    unsigned int message_digest[5];
    cout <<"server_key:"<< server_key << endl;
    sha.Reset();

    sha << server_key.c_str();
    sha.Result(message_digest);
    for (int i = 0; i < 5; i++) {
        message_digest[i] = htonl(message_digest[i]);
    }
    base64 base64_;
    server_key = base64_.base64_encode(reinterpret_cast<const unsigned char*>(message_digest), 20);
    server_key += "\r\n";
    strcat(request, server_key.c_str());
    strcat(request, "Upgrade: websocket\r\n\r\n");
}

至于代码中出现的sha1以及base64,,可以在以下链接中找到,本文就不再复制粘贴了:

https://blog.csdn.net/weixin_34196559/article/details/83479894

以上只是对握手协议进行了实现,但是实际使用中,在握手完成后,对于websocket发送来的数据,还需要进行解析,才可以获取数据,而且在解析时,还需要处理粘包半包等问题,留待下一篇文章进行阐述。

解析发送的数据,见我下一章:C++实现WebSocket解析协议

结尾:

只为记录,只为分享! 愿所写能对你有所帮助。不忘记点个赞,谢谢~

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++实现websocket服务器握手协议(使用Qt) 的相关文章

  • Node.js 和 WebSockets (Socket.io) 单元测试

    有人可以使用 WebSockets Socket io 为 Node js 提供坚如磐石 极其简单的单元测试吗 我在 Node js 中使用 socket io 并在测试中查看了 socket io client 来建立与服务器的客户端连接
  • 如何在 Python 中实现安全的 WebSocket (wss://) 服务器?

    我想提供一个实时流 由于敏感数据必须对其进行安全加密 我已经使用 gevent 和 Gunicorn 作为直接前端成功获得了正常的 WebSocket 流 但现在我需要确保其安全 并且正在寻找其中一个 可以提供安全 WebSocket 连接
  • Node.js ws 包上的正确错误处理

    我正在努力将基于 REST 的数据管道替换为基于 Websocket 的数据管道 但我无法找到所有可能出错的地方 该系统是生产系统 因此如果出现故障并且无法恢复 将会发生非常糟糕的情况 这是我到目前为止所得到的 客户端 let server
  • 为什么我的 wss://(基于 SSL/TLS 的 WebSockets)连接立即断开而不给出任何错误?

    将此发布给遇到同样问题的其他人 我当时正在开发一个浏览器客户端 它使用 stanza io 连接到 XMPP 服务器 在我的例子中是 Prosody 我默认使用 wss 连接 在开发过程中的某个时刻 我的客户端根本无法连接 它会立即无提示地
  • NodeJS Websocket如何在服务器重新启动时重新连接

    在 Node js 中我使用网络套接字 ws https github com websockets ws用于 WebSocket 连接 以下是客户端的代码 假设我们正在连接的服务器套接字宕机了一分钟 close 事件将会触发 但是每当服务
  • Websocket、Angular 2 和 JSON Web 令牌身份验证

    我的 Angular 2 应用程序 用打字稿编码 有一个简单的身份验证方案 用户登录 服务器返回 JSON Web 令牌 JWT abc123 在每次 API 调用时 应用程序都会将 JWT 发送到Authorization header
  • Socket.IO中的跨域连接

    是否可以跨域方式使用Socket IO 如果是这样 怎么办 网络上提到了这种可能性 但没有给出任何代码示例 引用socket io 常见问题解答 http socket io faq Socket IO支持跨域连接吗 当然 在每个浏览器上
  • 我可以在浏览器中启动 socket.io/websocket 服务器吗?

    之前有人问过这个问题 答案是否定的 但是现在 有了 browserify webpack 我可以像在服务器上那样编写代码吗 它会在浏览器中运行 还是有任何限制使这变得不可能 你不能 在浏览器中启动服务器需要访问浏览器中根本不存在的低级功能
  • Play框架2.5.0 Websockets示例[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 播放框架 2 5 0 Websockets 示例 在 play 2 5 0 websockets 代码
  • 如何使用 Scarlet 在 Android 上通过 WebSocket 进行连接?

    README md 中的代码 val scarletInstance Scarlet Builder webSocketFactory okHttpClient newWebSocketFactory GDAX URL addMessage
  • 通过nodejs服务器+socket.io从mp3文件同步流式传输音乐

    我的服务器上有一个 mp3 文件 我希望所有访问该网址的客户都能同步收听该音乐 That is 假设该文件播放 6 分钟 我在上午 10 00 开始播放这首歌 上午 10 03 发出的请求应从歌曲的第 3 分钟开始收听 我所有的客户都应该同
  • 客户端通过 websocket 连接从后端服务器数据库表检索数据

    我使用以下服务器代码从 postgres 数据库检索数据 const express require express const app express const server require http createServer app
  • 如何用Java处理来自客户端的Websocket消息?

    我正在使用 Websocket 用 Ja va 开发客户端 服务器应用程序 目前 所有客户端消息均使用 switch case 进行处理 如下所示 OnMessage public String onMessage String unscr
  • Netty:正确关闭 WebSocket

    如何从服务器端正确关闭 WebSocket 通道 连接 如果我使用一个ctx getChannel close the onerror在浏览器 Firefox 9 中抛出 页面加载时与 ws localhost 8080 websocket
  • HTTP/2 世界中的 WebSocket 替代方案是什么?

    新的 HTTP 2 协议具有一些有前途的功能 他们中有一些 多路复用 单个 TCP 连接可用于发出多个 HTTP 2 请求并接收多个响应 到单个源 HTTP 2 服务器推送 将服务器响应发送到客户端而不接收请求 即由服务器发起 双向连接 H
  • 使用服务器发送事件进行双向客户端-服务器通信(而不是 WebSocket)的缺点

    最近 我发现服务器发送事件是 WebSocket 的一种更简单的替代方案 用于从服务器进行推送 大多数比较它们的地方 例如here https stackoverflow com questions 5195452 websockets v
  • 在 Apache 上设置 websocket?

    所以我正在对 websockets 进行一些研究 我有几个问题似乎找不到明确的答案 如何在 Linux 服务器上设置 Web 套接字 有 Apache 模块吗 我可以吗have使用第 3 方 PHP 代码或类似代码 除了浏览器兼容性之外 问
  • 如何通过 libwebsocket 发送异步数据?

    我正在将 Warmcat 的 libwebsocket C 库用于小型 Websocket 服务器 我已经启动并运行了这些示例 并且可以发送数据以响应从 websocket 接收数据 例如回显发送的反向字节 但是 我无法弄清楚如何在不使用
  • 从 websocket 发送数据到 socket.io

    我使用 websocket 接口连接到 websocket 服务器 如果我想将通过 websocket 接口从 websocket 服务器接收到的数据发送到通过 http 服务器连接到我的客户端 我应该使用 socket io 吗 所以最后
  • 使用 HTML5 或 Javascript 的 P2P 视频会议

    我正在尝试使用 html5 和 javascript 构建视频会议 直到现在我能够流式传输我的相机捕获并将其显示在画布上 这是代码

随机推荐