日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

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

發(fā)布時間:2023/12/29 c/c++ 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++实现websocket服务器握手协议(使用Qt) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

前提:筆者在開發(fā)server程序時,要求websocket與server連接

websocket的機制是在第一次連接時進行握手協(xié)議,協(xié)議通過,才可以進行正常的通信,否則websocket就會斷開連接;

下面就是websocket第一次發(fā)送的握手包:

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發(fā)送來的第一個數(shù)據(jù)進行處理(判斷是否是第一個包,可以通過開頭GET來進行判斷,可能不是非常嚴(yán)謹(jǐn)),獲取Sec-WebSocket-Key的值(也就是上面的ikLk+bBgZDQRPTOBAzGsBg==),然后對此進行解析。

解析的方法是在key上加上固定字符串“258EAFA5-E914-47DA-95CA-C5AB0DC85B11”,再進行sha1解碼及base64編碼,然后打包發(fā)送給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接收數(shù)據(jù)if(!_firstConnect)//第一個包{_firstConnect = true;QString qstr_ = data_;//包數(shù)據(jù)轉(zhuǎn)化成QStringQString key_ = "";key_ = getKey(qstr_);if(key_ == "-1"){//自定義處理}else if(key_ == "-2"){//自定義處理}else{//處理keychar request[1024] = ""; //請求信息respondHandshake(request,key_.toStdString());QByteArray array_(request);write(array_);//發(fā)送數(shù)據(jù)給websocket客戶端}}else{//接下來包在此不做處理,需要涉及到websocket協(xié)議的解包} }/** *獲取Sec-WebSocket-Key的值,QT實現(xiàn) */ 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++實現(xiàn) */ 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"); }

至于代碼中出現(xiàn)的sha1以及base64,,可以在以下鏈接中找到,本文就不再復(fù)制粘貼了:

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

以上只是對握手協(xié)議進行了實現(xiàn),但是實際使用中,在握手完成后,對于websocket發(fā)送來的數(shù)據(jù),還需要進行解析,才可以獲取數(shù)據(jù),而且在解析時,還需要處理粘包半包等問題,留待下一篇文章進行闡述。

解析發(fā)送的數(shù)據(jù),見我下一章:C++實現(xiàn)WebSocket解析協(xié)議

結(jié)尾:

只為記錄,只為分享! 愿所寫能對你有所幫助。不忘記點個贊,謝謝~

總結(jié)

以上是生活随笔為你收集整理的C++实现websocket服务器握手协议(使用Qt)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。