Web Socket rfc6455 握 (C++)
2015-10-24 10:53
423 查看
std::string data((const char*)buf->data(),bytes_transferred); recycle_buffer(buf); std::string key="Sec-WebSocket-Key:"; auto pos = data.find(key); auto posEnd = data.find("\r\n",pos); auto value = data.substr(pos + key.length(),posEnd - (pos + key.length())); std::string sha1Src = trim(value); sha1Src += std::string("258EAFA5-E914-47DA-95CA-C5AB0DC85B11"); unsigned char sha1out[20]; sha1((const unsigned char *)sha1Src.c_str(),sha1Src.length(),sha1out); std::vector<unsigned char> data64; for( auto c: sha1out) data64.push_back(c); std::ostringstream os_rsp; os_rsp<<"HTTP/1.1 101 Switching Protocols\r\n" <<"Upgrade: websocket\r\n" <<"Connection: Upgrade\r\n" <<"Sec-WebSocket-Accept: "<<base64Encode(data64)<<"=\r\n" <<"\r\n"; std::string rsp = os_rsp.str();
1) data 为连接建立以后,web socketclient发送的握手协议。
2)查询到字段 Sec-WebSocket_key的值,而且拼接上GUID字符串"258EAFA5-E914-47DA-95CA-C5AB0DC85B11"值。
得到 sha1Src
3)对 key拼接后的值计算 sha1值,得到 sha1Out
4)应答,最基本的就是计算 Sec-WebSocket-Accept值。通过函数 base64Encode进行计算。
using namespace std; static const unsigned char bt[64]= { 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P', 'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f', 'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v', 'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/' }; std::string base64Encode(const std::vector<unsigned char> & data ){ std::list< std::bitset<8> > bits; for( auto c : data ){ std::bitset<8> bit(c); bits.push_back(bit); } while( bits.size() % 3 != 0 ) bits.push_back( bitset<8>() ); std::vector<unsigned char> base64; while( !bits.empty() ){ std::bitset<6> bit6_1,bit6_2,bit6_3,bit6_4; std::bitset<8> bit8_1 = *bits.begin(); bits.pop_front(); std::bitset<8> bit8_2 = *bits.begin(); bits.pop_front(); std::bitset<8> bit8_3 = *bits.begin(); bits.pop_front(); bit6_1.set(0, bit8_1[2]); bit6_1.set(1, bit8_1[3]); bit6_1.set(2, bit8_1[4]); bit6_1.set(3, bit8_1[5]); bit6_1.set(4, bit8_1[6]); bit6_1.set(5, bit8_1[7]); bit6_2.set(0, bit8_2[4]); bit6_2.set(1, bit8_2[5]); bit6_2.set(2, bit8_2[6]); bit6_2.set(3, bit8_2[7]); bit6_2.set(4, bit8_1[0]); bit6_2.set(5, bit8_1[1]); bit6_3.set(0, bit8_3[6]); bit6_3.set(1, bit8_3[7]); bit6_3.set(2, bit8_2[0]); bit6_3.set(3, bit8_2[1]); bit6_3.set(4, bit8_2[2]); bit6_3.set(5, bit8_2[3]); bit6_4.set(0, bit8_3[0]); bit6_4.set(1, bit8_3[1]); bit6_4.set(2, bit8_3[2]); bit6_4.set(3, bit8_3[3]); bit6_4.set(4, bit8_3[4]); bit6_4.set(5, bit8_3[5]); base64.push_back( bt[bit6_1.to_ulong() ]); base64.push_back( bt[bit6_2.to_ulong() ]); base64.push_back( bt[bit6_3.to_ulong() ]); base64.push_back( bt[bit6_4.to_ulong() ]); } base64.pop_back(); string strdata(base64.begin(),base64.end()); return strdata; }
5) 计算后把RSP发生出去能够。
相关文章推荐
- IOS开发笔记7-函数-C语言笔记
- char,short ,int ,long,long long,unsigned long long数据范围
- C语言中cos(x)或sin(x),x输入的是弧度,怎么输入角度
- Leetcode Minimum Size Subarray Sum
- C#调用C++ dll时CallingConvention调用约定详解
- C++静态库与动态库
- c++学习笔记(十):运算符重载综合——自定义数组类
- 【C/C++学院】0820-Nullptr/const对象/类指针引用以及mallocfree与newde/类重载运算符/QT加法重载/类的重载赋值运算/自增在前在后差别/赋值重载深浅拷贝/重载下标
- VC++ WINDOWS自定义消息范围
- 黑马程序员——OC语言日志——NSString字符串的比较函数
- 第19讲----项目2 C语言中的字符对齐
- C++调用C函数,为什么要加extern "C"?
- Leetcode NO.249 Group Shifted Strings
- C++调用python
- C++模板与泛型编程基础
- python 调用 C++ code
- C++常见容器概述
- 使用NDK生成native C/C++的可执行程序
- 三个数找最大 2.0
- C语言位运算