一.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. [skill][msgpack] 初试msgpack库以及基本使用

    It's like JSON.   but fast and small. http://msgpack.org/index.html 源码: https://github.com/msgpack/m ...

  2. c++ Stl 随笔

    1. template <class InputIterator, class Distance> void advance (InputIterator& it, Distanc ...

  3. spring quartz动态修改执行时间

    1.获取schedule <bean name="startQuartz" lazy-init="false" autowire="no&quo ...

  4. JavaWeb开发如何用Tomcat部署发布

    一.如何安装TomCat 1.1安装包下载地址:https://tomcat.apache.org/download-70.cgi 1.2  安装exe文件,下一步直到安装成功.并启动Tomcat服务 ...

  5. JavaScript学习笔记--语法

    代码风格: 每句结尾不用加分号: 单行注释用//,多行注释用/*...需要注释掉的代码....*/ 严格区分大小写 优雅的代码需要注意锁进 基础知识: Number:JavaScript不区分整数和浮 ...

  6. Es6 的类(class)

    首先根据es5的类(原型对象)的基本点做参照. 序号 基本点 es5 >es6 1 实例属性(方法) √ √ 2 原型属性(方法) 或 公共属性(方法) √ √ 3 es5的私有变量 或 私有属 ...

  7. Log4j rootLogger配置

    Log4j 根配置语法 log4j.rootLogger = [ level ] , appenderName, appenderName, … 指代 把指定级别的日志信息输出到指定的一个或者多个位置 ...

  8. 谈谈javascript数组排序方法sort()的使用,重点介绍参数使用及内部机制?

    语法:arrayObject.sort(sortby) 参数sortby可选,规定排序顺序,必须是函数: 注:如果调用该方法时没有使用参数,将按字符编码的顺序进行排序,要实现这一点,首先应把数组的元素 ...

  9. Oracle 11g服务详细介绍及哪些服务是必须开启的

    成功安装Oracle 11g后,共有7个服务,这七个服务的含义分别为: 1. Oracle ORCL VSS Writer Service: Oracle卷映射拷贝写入服务,VSS(Volume Sh ...

  10. 20170921 DEV功能页面

    环境:vs2013 DEV第三方控件 后端使用Linq to sql , lambda 表达式 页面格式