websocket发送接收协议
一.websocket接收数据

1)固定字节(1000 0001或1000 0010); ---区分是否是数据包的一个固定字节(占1个字节)
2)包长度字节,第位是1, 剩下为得到一个整数(0,127);125以内的长度直接表示就可以了;表示后面两个字节表示大小,127表示后面的个字节是数据的长度;
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);
}
websocket发送接收协议的更多相关文章
- C# WebSocket模拟发送接收
WebSocket服务端 C#示例代码 using System; using System.Collections.Generic; using System.Linq; using System. ...
- 网络编程--使用TCP协议发送接收数据
package com.zhangxueliang.tcp; import java.io.IOException; import java.io.OutputStream; import java. ...
- [转帖]Linux TCP/IP协议栈,数据发送接收流程,TCP协议特点
Linux TCP/IP协议栈,数据发送接收流程,TCP协议特点 http://network.51cto.com/art/201909/603780.htm 可以毫不夸张的说现如今的互联网是基于TC ...
- Qt5 基于TCP传输的发送/接收文件服务器(支持多客户端)
一.实现功能 1.服务器端选择待发送的文件,可以是多个 2.开启服务器,支持多客户端接入,能够实时显示每个客户端接入状态 3.等待所有客户端都处于已连接状态时,依次发送文件集给每个客户端,显示每个客户 ...
- 转-Web Service中三种发送接受协议SOAP、http get、http post
原文链接:web服务中三种发送接受协议SOAP/HTTP GET/HTTP POST 一.web服务中三种发送接受协议SOAP/HTTP GET/HTTP POST 在web服务中,有三种可供选择的发 ...
- 网络编程--使用UDP发送接收数据
package com.zhangxueliang.udp; import java.io.IOException; import java.net.DatagramPacket; import ja ...
- C# Socket模拟发送接收
Socket简介 通过TCP/IP与仪器或设备通讯,在C#语言中,我们通常采用Socket.本项目是一个简单的Socket建立服务监听与Socket作为客户端请求的一个示例. 项目结构 客户端项目 S ...
- springboot成神之——websocket发送和请求消息
本文介绍如何使用websocket发送和请求消息 项目目录 依赖 DemoApplication MessageModel WebConfig WebSocketConfig HttpHandshak ...
- [NIO]用dawn发送接收HTTP请求
HTTP协议的下层使用的是tcp.所以我们建立一个tcp连接就能发送接收http请求.dawn底层使用了nio.可是经过dawn的封装之后,我们在编写代码的时候,就和使用普通的堵塞式socket一样 ...
随机推荐
- [development][tcp/ip][ids] 一个简单有参考价值的库 libnids
libhtp 中的例子, 可以通过libnids快速使用. 或者可以快速的写个sniffer. 支持三个功能 ip分片重组, tcp乱序重排, 端口扫描发现. 工程: https://github.c ...
- hash_map
点开一道第是自己oj的第440大关,想a了,一直想却无果,学长一句点醒,开始写hash. 关于这道题呢很无语了,两天卡在这上面,而且有些dalao不到20min就a了.我太菜了. 所以要深入讨论这道题 ...
- ubuntu物理机上搭建Kubernetes集群 -- minion 配置
1. flannel配置 下载二进制文件 https://github.com/coreos/flannel/releases 版本:flannel-v0.7.0-linux-amd64.tar.gz ...
- 转:GET和POST两种基本请求方法的区别
原文地址:GET和POST两种基本请求方法的区别 原文如下: GET和POST是HTTP请求的两种基本方法,要说它们的区别,接触过WEB开发的人都能说出一二. 最直观的区别就是GET把参数包含在URL ...
- Android SDK 环境搭建
Android SDK(Software Development Kit,软件开发工具包)提供了 Android API 库和开发工具构建,测试和调试应用程序.简单来讲,Android SDK 可以看 ...
- Python开发【笔记】:从海量文件的目录中获取文件名--方法性能对比
Python获取文件名的方法性能对比 前言:平常在python中从文件夹中获取文件名的简单方法 os.system('ll /data/') 但是当文件夹中含有巨量文件时,这种方式完全是行不通 ...
- SpringBoot 使用RedisTemplate操作Redis
新版: import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.T ...
- USB驱动框架
以USB鼠标驱动为例 框架入口源文件: usb_mouse.c hub.c (可根据入口源文件,再按着框架到内核走一遍) 内核版本:linux_2.6.22.6 硬件平台:JZ2440 以下是 ...
- python3安装ipython 过程以及问题
由于需要再python3的环境下运行demo,因此安装了python3的ipython notebook,过程如下: sudo pip3 install ipython[all]这样就安装了pytho ...
- 【托业】【新托业TOEIC新题型真题】学习笔记1--题库一-->P1~4
P1~4--------------------------------------单词-------------------------------------- status 雕像 couple ...