一.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. pause

    https://stackoverflow.com/questions/37063700/mm-pause-usage-in-gcc-on-intel?utm_medium=organic&u ...

  2. [DPI][suricata] suricata-4.0.3 安装部署

    suricata 很值得借鉴.但是首先还是要安装使用,作为第一步的熟悉. 安装文档:https://redmine.openinfosecfoundation.org/projects/suricat ...

  3. [administrative][qemu][kvm] qemu使用--bridge-helper

    公司服务器,源码安装的 qemu-2.9.0. 不是yum装的. 问题1:非超级用户的kvm权限问题: 略,直接超级用户使用. 也许有用? https://access.redhat.com/docu ...

  4. 彻底卸载tv

    1.卸载 2.C:\Program Files (x86),找到teamviewer选项,右击删除 3.开始--输入regedit,打开注册表,找到如下路径:HKEY_LOCAL_MACHINE\SO ...

  5. 清理solaris /var/mail/下的邮件文件

    我服务器上/var/mail下的各个用户的邮件日志非常大,占用空间已经有95%了,我想清除掉,是否可以直接删除/var/mail的各个日志??删除后系统是否可以自动生成? 应该可以直接删除/var/m ...

  6. 转:JAVA中解决Filter过滤掉css,js,图片文件等问题

    原文链接:https://www.cnblogs.com/ermeng/p/6440966.html public void doFilter(ServletRequest request, Serv ...

  7. vue脚手架用axios请求本地数据

    首先需要声明的是:本地请求,不用考虑跨域问题,这适用刚入坑的前端小白看,小白在做自己的项目时,通常都是用自己写的json数据,之后用axios请求过来,渲染到页面上. 1.cnpm install a ...

  8. SQL Server的一些小问题

    一.SQL Server远程调用失败 解决办法:在控制面板-程序和功能中卸载“Microsoft SQL Server 2012 Express LocalDB”,具体版本根据你安装的VS版本决定,我 ...

  9. Javabean非空变量校验工具

    摘要 调研java Class getDeclaredFields() 与getFields()的区别,设计请求参数为Javabean时,基于反射机制校验其中非空变量的公共方法. java Class ...

  10. caffe中在某一层获得迭代次数的方法以及caffe编译时报错 error: 'to_string' is not a member of 'std'解决方法

    https://stackoverflow.com/questions/38369565/how-to-get-learning-rate-or-iteration-times-when-define ...