一.websocket接收数据
1)固定字节(1000 0001或1000 0010); ---区分是否是数据包的一个固定字节(占1个字节)
2)包长度字节,第1位是1, 剩下7为得到一个整数(0,127);125以内的长度直接表示就可以了;126表示后面两个字节表示大小,127表示后面的8个字节是数据的长度;
3)mark 掩码为包长之后的 4 个字节
4)兄弟数据:
得到真实数据的方法:将兄弟数据的每一字节 x,和掩码的第 i%4 字节做 xor运算,其中i 是x 在兄弟数据中的索引
测试代码:
void on_ws_recv_data(struct session* s,unsigned char* pkg_data,int pkg_len) {
//第一个字节是头,忽略
//end
unsigned int len = pkg_data[1];
unsigned char* raw_data = NULL; //数据开始位置指针
unsigned char* mask = NULL; //掩码开始位置指针
//最高一个bit始终是1,我们要把最高位这个bit变为0后即为数据长度
len &= 0x0000007f; //len数据长度
if (len < 126){
mask = pkg_data + 2;
}
else if (len == 126){ //126时后面两个字节表示长度
len = ((pkg_data[2]) | (pkg_data[3] << 8));
mask = pkg_data + 2 + 2;
}
else if(len == 127) { //127时后面八个字节表示长度一般只考虑前4个字节
//忽略
int low = ((pkg_data[2]) | (pkg_data[3] << 8) | (pkg_data[4] << 16) | (pkg_data[5] << 24));
int hight = ((pkg_data[6]) | (pkg_data[7] << 8) | (pkg_data[8] << 16) | (pkg_data[9] << 24));
if (hight != 0) //四个字节放不下 忽略掉
{
return;
}
mask = pkg_data + 2 + 8;
}
//数据部分开始的指针
raw_data = mask + 4;
static unsigned char raw_recvbuf[4096] = { 0 };
//还原发过来的数据
//数据从第9个字节开始与对应的掩码异或 /循环4个字节掩码异或
for (int i = 0; i < len; i++)
{
raw_recvbuf[i] = raw_data[i] ^ mask[i%4];
}
raw_recvbuf[len] = 0;
printf("=====================\n");
printf("recv data:\n%s\n", raw_recvbuf);
//char* test = "server: hello!";
//ws_send_data(s, test, strlen(test));
}
二.websocket发送数据
测试代码:
void ws_send_data(struct session* s, unsigned char* pkg_data, int pkg_len) {
static unsigned char send_buffer[8096];
unsigned int send_len = 0;
//固定的头
send_buffer[0] = 0x81;
if ( pkg_len <= 125 ) {
//数据长度小于1个字节
send_buffer[1] = pkg_len; //最高bit位为0 不用管
send_len = 2;
}else if( pkg_len <= 0xFFFF ) {
//数据长度小于2个字节
send_buffer[1] = 126;
send_buffer[2] = pkg_len & 0x000000FF;
send_buffer[3] = (pkg_len & 0x0000FF00) >> 8;
send_len = 4;
}else {
//数据长度为8个字节
send_buffer[1] = 127;
send_buffer[2] = pkg_len & 0x000000FF;
send_buffer[3] = (pkg_len & 0x0000FF00) >> 8;
send_buffer[4] = (pkg_len & 0x00FF0000) >> 16;
send_buffer[5] = (pkg_len & 0xFF000000) >> 24;
send_buffer[6] = 0;
send_buffer[7] = 0;
send_buffer[8] = 0;
send_buffer[9] = 0;
send_len = 10;
}
memcpy(send_buffer + send_len, pkg_data, pkg_len);
send_len += pkg_len;
//发送数据
send(s->c_sock, send_buffer, send_len, 0);
}