Update for cmake

master
Kirigaya Kazuto 2018-09-17 18:29:44 +08:00
parent f43e8b9710
commit ab3f2510fe
3 changed files with 44 additions and 34 deletions

2
CMakeLists.txt Normal file
View File

@ -0,0 +1,2 @@
add_subdirectory(GSock)
add_library(LibWS sha1.cpp websocket.cpp)

View File

@ -9,28 +9,16 @@
#include <WinSock2.h> // htonl #include <WinSock2.h> // htonl
using namespace std; using namespace std;
int HandleKey(sock& s, const string& key) string GetResponseKey(const string& key)
{ {
string server_key = key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; string server_key = key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
SHA1 sha; SHA1 sha;
sha.update(server_key); sha.update(server_key);
uint32_t arr[5]; uint32_t arr[5];
sha.final(arr); sha.final(arr);
for (int i = 0; i < 5; i++) arr[i] = htonl(arr[i]); // 重要 // 必须转换成网络字节序
string response_key = base64_encode_std((const unsigned char*)arr, sizeof(arr)); for (int i = 0; i < 5; i++) arr[i] = htonl(arr[i]);
sock_helper sp(s); return base64_encode_std((const unsigned char*)arr, sizeof(arr));
string response_header = string("HTTP/1.1 101 Switching Protocols\r\n") +
"Connection: upgrade\r\n" +
"Sec-WebSocket-Accept: " + response_key + "\r\n" +
"Upgrade: websocket\r\n\r\n";
if (sp.sendall(response_header) <= 0)
{
return -1;
}
else
{
return 0;
}
} }
int Handshake(sock& s) int Handshake(sock& s)
@ -47,21 +35,26 @@ int Handshake(sock& s)
// cout << str << endl; // cout << str << endl;
} }
string target("Sec-WebSocket-Key");
for (auto& str : lines) for (auto& str : lines)
{ {
string target("Sec-WebSocket-Key");
if (str.find(target) != string::npos) if (str.find(target) != string::npos)
{ {
string key = str.substr(str.find(target) + 19, 24); string key = str.substr(str.find(target) + 19, 24);
if (HandleKey(s, key) == 0) string response_key = GetResponseKey(key);
string response_header = string("HTTP/1.1 101 Switching Protocols\r\n") +
"Connection: upgrade\r\n" +
"Sec-WebSocket-Accept: " + response_key + "\r\n" +
"Upgrade: websocket\r\n\r\n";
if (sp.sendall(response_header) <= 0)
{ {
// Handshake OK // Network error.
return 0; return -1;
} }
else else
{ {
// Handshake Failed: Key is not ok // Handshake finished successfully.
return -1; return 0;
} }
} }
} }
@ -110,7 +103,7 @@ int ReadFrame(sock& s, WSFrame& f)
if (sp.recvall(xp.get(), f.len) <= 0) return -1; if (sp.recvall(xp.get(), f.len) <= 0) return -1;
if (f.ismask) if (f.ismask)
{ {
// 处理掩码问题 // 处理掩码问题
for (unsigned long long i = 0; i < f.len; i++) for (unsigned long long i = 0; i < f.len; i++)
{ {
xp[i] ^= f.mask[i % 4]; xp[i] ^= f.mask[i % 4];
@ -198,18 +191,18 @@ int ReadMsg(sock& s, string& out_data)
{ {
int ret = ReadFrame(s, f); int ret = ReadFrame(s, f);
if (ret < 0) return -1; if (ret < 0) return -1;
if (f.opcode == 0x9) // ping包则回复一个pong包 if (f.opcode == 0x9) // ping包则回复一个pong包
{ {
cout << "Received ping from " << (&s) << endl; cout << "Received ping from " << (&s) << endl;
if (SendPong(s, f) < 0) return -2; if (SendPong(s, f) < 0) return -2;
continue; continue;
} }
else if (f.opcode == 0xA) // pong包则什么都不做 else if (f.opcode == 0xA) // pong包则什么都不做
{ {
cout << "Received pong from " << (&s) << endl; cout << "Received pong from " << (&s) << endl;
continue; continue;
} }
else if (f.opcode == 0x8) // 连接主动关闭 else if (f.opcode == 0x8) // 连接主动关闭
{ {
cout << "Websocket is closing " << (&s) << endl; cout << "Websocket is closing " << (&s) << endl;
return 0; return 0;

View File

@ -2,9 +2,17 @@
#include <string> #include <string>
#include "GSock/gsock.h" #include "GSock/gsock.h"
int HandleKey(sock& s, const std::string& key); // 获取Sec-WebSocket-Key的结果
std::string GetResponseKey(const std::string& key);
// 完成Websocket握手过程(http头获取和发送)
// 返回值:
// 0 握手成功
// -1 网络连接中断
// -2 请求的不是websocket协议/非法的ws请求
int Handshake(sock& s); int Handshake(sock& s);
// WebSocket数据帧
struct WSFrame struct WSFrame
{ {
// 1 bit // 1 bit
@ -12,14 +20,14 @@ struct WSFrame
// 1 bit // 1 bit
bool rsv1, rsv2, rsv3; bool rsv1, rsv2, rsv3;
// 0x0 附加数据帧 // 0x0 附加数据帧
// 0x1 文本数据帧 // 0x1 文本数据帧
// 0x2 二进制数据帧 // 0x2 二进制数据帧
// 0x3~7 保留 // 0x3~7 保留
// 0x8 连接关闭 // 0x8 连接关闭
// 0x9 ping // 0x9 ping
// 0xA pong // 0xA pong
// 0xB~F 保留 // 0xB~F 保留
// 4 bit // 4 bit
int opcode; int opcode;
@ -29,12 +37,19 @@ struct WSFrame
// 4 byte // 4 byte
char mask[4]; char mask[4];
// data是未经过编码处理的数据(如果源数据是带掩码的则已经经过解掩码处理) // data是未经过编码处理的数据(如果源数据是带掩码的则已经经过解掩码处理)
std::string data; std::string data;
}; };
// 读写单个数据帧
int ReadFrame(sock& s, WSFrame& f); int ReadFrame(sock& s, WSFrame& f);
int SendFrame(sock& s, const WSFrame& f); int SendFrame(sock& s, const WSFrame& f);
// 发送对ping的响应
int SendPong(sock& s, const WSFrame& ping); int SendPong(sock& s, const WSFrame& ping);
// 读写数据
// 读取时可能会读取多个数据帧,同时也会自动对ping包进行响应.
// 写入时不会分为多个数据帧.
int ReadMsg(sock& s, std::string& out_data); int ReadMsg(sock& s, std::string& out_data);
int SendMsg(sock& s, const std::string& data, bool is_text = true); int SendMsg(sock& s, const std::string& data, bool is_text = true);