一.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发送接收协议的更多相关文章

  1. C# WebSocket模拟发送接收

    WebSocket服务端 C#示例代码 using System; using System.Collections.Generic; using System.Linq; using System. ...

  2. 网络编程--使用TCP协议发送接收数据

    package com.zhangxueliang.tcp; import java.io.IOException; import java.io.OutputStream; import java. ...

  3. [转帖]Linux TCP/IP协议栈,数据发送接收流程,TCP协议特点

    Linux TCP/IP协议栈,数据发送接收流程,TCP协议特点 http://network.51cto.com/art/201909/603780.htm 可以毫不夸张的说现如今的互联网是基于TC ...

  4. Qt5 基于TCP传输的发送/接收文件服务器(支持多客户端)

    一.实现功能 1.服务器端选择待发送的文件,可以是多个 2.开启服务器,支持多客户端接入,能够实时显示每个客户端接入状态 3.等待所有客户端都处于已连接状态时,依次发送文件集给每个客户端,显示每个客户 ...

  5. 转-Web Service中三种发送接受协议SOAP、http get、http post

    原文链接:web服务中三种发送接受协议SOAP/HTTP GET/HTTP POST 一.web服务中三种发送接受协议SOAP/HTTP GET/HTTP POST 在web服务中,有三种可供选择的发 ...

  6. 网络编程--使用UDP发送接收数据

    package com.zhangxueliang.udp; import java.io.IOException; import java.net.DatagramPacket; import ja ...

  7. C# Socket模拟发送接收

    Socket简介 通过TCP/IP与仪器或设备通讯,在C#语言中,我们通常采用Socket.本项目是一个简单的Socket建立服务监听与Socket作为客户端请求的一个示例. 项目结构 客户端项目 S ...

  8. springboot成神之——websocket发送和请求消息

    本文介绍如何使用websocket发送和请求消息 项目目录 依赖 DemoApplication MessageModel WebConfig WebSocketConfig HttpHandshak ...

  9. [NIO]用dawn发送接收HTTP请求

    HTTP协议的下层使用的是tcp.所以我们建立一个tcp连接就能发送接收http请求.dawn底层使用了nio.可是经过dawn的封装之后,我们在编写代码的时候,就和使用普通的堵塞式socket一样 ...

随机推荐

  1. kafka后台启动的命令

    kafka如果直接启动会出现问题,就是信息会打印在控制台,就会出现在控制台. 然后关闭窗口,kafka随之关闭,然后启动以下的命令就可以实现. ./kafka-server-start.sh ../c ...

  2. 关于swagger-ui 参数为中文的时候,后端乱码

    项目中用swagger-ui来测试接口,但是发现,参数是中文的时候,后台接收的时候会出现乱码. 不得改用postman,就没事了, 立贴求助,希望有人可以说下这个怎么配置. 后面发现是后端的编码过滤器 ...

  3. Java基础知识之锁

    Java中实现锁的方式有多种,并且锁的分类也有很多,这篇文章会从锁分类方面简单介绍各分类的锁的特点. 悲观锁和乐观锁 悲观锁:先假设别人也会对数据就行修改,所以先获得锁再进行操作.一个县城在获得锁之后 ...

  4. Orchard Core 增加了一个API模块,要怎么调用

    如下,我在Orchard Core框架中添加了一个API的模块,并且定义了对应的权限才可以调用,那么我们现在考虑的就是要怎么去调用它. 首先,我们用Fiddler查看下我们正常的登录的http报文,直 ...

  5. 【Python全栈-数据库】数据库基础

    数据库的简介 数据库 数据库(database,DB)是指长期存储在计算机内的,有组织,可共享的数据的集合.数据库中的数据按一定的数学模型组织.描述和存储,具有较小的冗余,较高的数据独立性和易扩展性, ...

  6. JavaScript 学习笔记-HTML&&DOM

    HTML DOM (文档对象模型) 当网页被加载时,浏览器会创建页面的文档对象模型(Document Object Model). HTML DOM 模型被构造为对象的树. JavaScript 能够 ...

  7. 10.8-uC/OS-III内部任务(中断处理任务 OS_IntQTask())

    1.当设置OS_CFG.H中的OS_CFG_ISR_POST_DEFERRED_EN为1时, uC/OS-III就会创建一个任务,它的作用是尽快完成ISR中对post函数的调用, 将信号量.消息等对象 ...

  8. Spring对Bean装配详解

    1.Spring提供了三种装配bean的方式: 2.自动装配bean: 3.通过Java代码装配bean 4.通过XML装配bean 前言:创建对象的协作关系称为装配,也就是DI(依赖注入)的本质.而 ...

  9. 关于Redis的配置

    Redis-配置 1. Redis默认不是以守护进程的方式运行,可以通过该配置项修改,使用yes启用守护进程 daemonize no 2. 当Redis以守护进程方式运行时,Redis默认会把pid ...

  10. NgDL:第三周:浅层NN

    1.激活函数 1.tanh函数比sigmoid效果更好,它的区间是[-1,1],所以均值为0,有类似于让数据中心化的效果. //此时Ng说,tanh函数几乎在所有场合都更优越. 2.但是如果yhat是 ...