TCP客户端模拟链接websocket服务端发送消息(二)

兄弟们,我来填坑了,o(╥﹏╥)o o(╥﹏╥)o o(╥﹏╥)o o(╥﹏╥)o o(╥﹏╥)o o(╥﹏╥)o,前几天写了个tcp模拟websocket客户端的以为完成,后面需要发送消息给服务端,以为简单不就是一个发送消息么,这不是一下的事情,诺 sslStrem.Write(bt,0,bt.length);这不就是么,结果结果啪啪啪打脸,脸都要肿了o(╥﹏╥)o o(╥﹏╥)o o(╥﹏╥)o。

错误信息:“xeaThe client frame was not masked but all client frames must be masked” 后面查找资料发现需要按照websocket协议来发送websocket结构体的消息帧。

如下图

WebSocket 消息帧结构

    FIN(1位): 表示是否是最后一帧。
    RSV1, RSV2, RSV3(各1位): 保留位,通常为 0。
    Opcode(4位): 帧的类型(例如:文本帧、二进制帧、关闭帧等)。
    Mask(1位): 表示负载是否被掩码。
    Payload length(7/7+16/7+64位): 表示负载数据的长度。
    Masking key(32位): 如果 Mask 为 1,则存在掩码键。
    Payload data: 实际传输的数据。

找了一大堆资料结果还是没成功,一想到有开源的websocket开源代码里面肯定是有发送消息的方法。得按照这个思路在websocket-sharp开源里找到了,然后在里面看啊看游啊游,头都要大了,最后还是仿写了一套相对简单的,后面一试成功了不容易啊。

代码如下:

   public void Send2(string data){byte[] bytes = Encoding.UTF8.GetBytes(data);Stream sourceStream = new MemoryStream(bytes);try{var len = sourceStream.Length;if (len == 0){bool sent3 = send2(0x1, 0x1, new byte[0], false);return;}var quo = len / 1016;var rem = (int)(len % 1016);byte[] buff = null;if (quo == 0){buff = new byte[rem];bool sent2 = sourceStream.Read(buff, 0, rem) == rem && send2(0x1, 0x1, buff, false);return;}if (quo == 1 && rem == 0){buff = new byte[1016];bool sent2 = sourceStream.Read(buff, 0, 1016) == 1016 && send2(0x1, 0x1, buff, false);return;}/* Send fragments */// Beginbuff = new byte[1016];var sent = sourceStream.Read(buff, 0, 1016) == 1016 && send2(0x0, 0x1, buff, false);if (!sent)return;// Continuevar n = rem == 0 ? quo - 2 : quo - 1;for (long i = 0; i < n; i++){sent = sourceStream.Read(buff, 0, 1016) == 1016 && send2(0x0, 0x0, buff, false);if (!sent)return;}// Endif (rem == 0)rem = 1016;elsebuff = new byte[rem];sent = sourceStream.Read(buff, 0, rem) == rem && send2(0x1, 0x0, buff, false);return;}catch{}finally{sourceStream.Dispose();}}private bool send2(byte fin, byte opcode, byte[] data, bool compressed){byte _payloadLength;byte _rsv1;byte _rsv2;byte _rsv3;byte[] _extPayloadLength;byte[] _maskingKey;byte _mask;//PayloadData _payloadData = new PayloadData(data);_rsv1 = compressed ? (byte)0x1 : (byte)0x0;_rsv2 = 0x0;_rsv3 = 0x0;var len = data.Length;if (len < 126){_payloadLength = (byte)len;_extPayloadLength = new byte[0];}else if (len < 0x010000){_payloadLength = (byte)126;var ret = BitConverter.GetBytes((ushort)len);Array.Reverse(ret);_extPayloadLength = ret;//_extPayloadLength = ((ushort)len).ToByteArray(ByteOrder.Big);}else{_payloadLength = (byte)127;var ret = BitConverter.GetBytes((ulong)len);Array.Reverse(ret);_extPayloadLength = ret;//_extPayloadLength = ((ulong)len).ToByteArray(ByteOrder.Big);}if (true){_mask = 0x1;var key = new byte[4];RNGCryptoServiceProvider RandomNumber = new RNGCryptoServiceProvider();RandomNumber.GetBytes(key);_maskingKey = key;for (long i = 0; i < data.Length; i++){data[i] = (byte)(data[i] ^ key[i % 4]);}}using (var buff = new MemoryStream()){var header = (int)fin;header = (header << 1) + (int)_rsv1;header = (header << 1) + (int)_rsv2;header = (header << 1) + (int)_rsv3;header = (header << 4) + (int)opcode;header = (header << 1) + (int)_mask;header = (header << 7) + (int)_payloadLength;var uint16Header = (ushort)header;var ret = BitConverter.GetBytes(uint16Header);Array.Reverse(ret);var rawHeader = ret;buff.Write(rawHeader, 0, 2);if (_payloadLength >= 126)buff.Write(_extPayloadLength, 0, _extPayloadLength.Length);if (_mask == 0x1)buff.Write(_maskingKey, 0, 4);if (_payloadLength > 0){var bytes = data;if (_payloadLength > 126){using (var src = new MemoryStream(bytes))src.CopyTo(buff, 1024);}elsebuff.Write(bytes, 0, bytes.Length);}buff.Close();var rawFrame = buff.ToArray();try{sslStream.Write(rawFrame, 0, rawFrame.Length);}catch{return false;}return true;}}

https://download.csdn.net/download/qq_35319925/90187478icon-default.png?t=O83Ahttps://download.csdn.net/download/qq_35319925/90187478 上面提供了代码链接下载地址。获取电脑本地的音频设备并实时传输音频数据到后台。这个demo是可以跑通的。方便大家使用

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/497577.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LVGL——基础对象篇

LVGL——基础对象篇 基础对象篇部件大小位置设置部件位置&#xff08;position&#xff09;设置相关API函数&#xff1a; 对齐对齐方式 样式给部件添加样式添加普通样式添加本地样式样式触发时机设置单独设置部件中某个部分的样式 事件事件&#xff08;events&#xff09;相关A…

【机器学习】机器学习的基本分类-半监督学习(Semi-supervised Learning)

半监督学习是一种介于监督学习和无监督学习之间的机器学习方法。它利用少量的标注数据&#xff08;有监督数据&#xff09;和大量的未标注数据&#xff08;无监督数据&#xff09;来进行模型训练&#xff0c;从而在标注数据不足的情况下&#xff0c;提升模型的性能。 半监督学习…

coturn docker 项目 搭建【一切正常】

业务需求&#xff1a;需要coturn这个服务 定制语音视频连线 请参考"小红的逃脱外星人追踪计划" coturn项目 本地测试连接服务 turnutils_stunclient -p 3478 127.0.0.1turnutils_stunclient -p 3478 -L 127.0.0.1 127.0.0.1telnet localhost 3478turnutils_uclient …

WOFOST作物模型(3):(本地化校准)优化PCSE模型中的参数

目录 一、准备自己的LAI观测数据二、优化参数三、损失函数四、NLOPT优化五、优化结果可视化一、准备自己的LAI观测数据 在进行田间实测后,得到自己的LAI观测数据 在程序这个地方输入自己的LAI采样日期和观测值 二、优化参数 这里主要选择了TDWI(Total Dry Weight at ger…

Webpack学习笔记(6)

首先搭建一个基本的webpack环境&#xff1a; 执行npm init -y&#xff0c;创建pack.json&#xff0c;保存安装包的一些信息 执行npm install webpack webpack-cli webpack-dev-server html-webpack-plugin -D&#xff0c;出现node_modules和package-lock.json。 1.source-Ma…

嵌入式开发中的机器人表情绘制

机器人的表情有两种&#xff0c;一种是贴图&#xff0c;一钟是调用图形API自绘。 贴图效果相对比较好&#xff0c;在存储空间大的情况下是可以采用的。 自绘比较麻烦&#xff0c;但在资源和空缺少的情况下&#xff0c;也是很有用的。而且自绘很容易通过调整参数加入随机效果&…

表单元素(标签)有哪些?

HTML 中的表单元素&#xff08;标签&#xff09;用于收集用户输入的数据&#xff0c;常见的有以下几种&#xff1a; 文本输入框 <input type"text">&#xff1a;用于单行文本输入&#xff0c;如用户名、密码等。可以通过设置maxlength属性限制输入字符数&…

探索CSDN博客数据:使用Python爬虫技术

探索CSDN博客数据&#xff1a;使用Python爬虫技术 在数字化的浪潮中&#xff0c;数据的获取与分析变得日益关键。CSDN作为中国领先的IT社区和服务平台&#xff0c;汇聚了海量的技术博客与文章&#xff0c;成为一座蕴藏丰富的数据宝库。本文将引领您穿梭于Python的requests和py…

图像处理(大津法找阈值)

1.摄像头获取到一帧的图片&#xff1a; 2.将在图片中把赛道识别出来&#xff1a; 利用大津法将图片进行二值化&#xff0c;把大致赛道从图中区分出来&#xff1a; 3.对进行二值化之后的图像进行处理&#xff0c;将非赛道部分都进行补画&#xff0c;最后要得到一个明显的赛道图&…

vulnhub靶机driftingblues6

开启靶机 扫ip 扫目录 扫端口 访问扫到的ip 192.168.146.156 访问/robots.txt 有目录/textpattern/textpattern 提示不要忘记zip 访问 /textpattern/files目录是网站目录页面 访问目录/textpattern/textpattern 发现登陆页面 访问/textpattern/README 看到网站为Textpattern C…

Xilinx PCIe高速接口入门实战(三)

引言&#xff1a;为保证FPGA设备可以连接并被系统识别&#xff0c;本节讨论了PCIe基础规范和PCIe板卡电气规范的对FPGA配置时间具体要求。 1. 配置访问时间 在PCIe的标准系统中&#xff0c;当系统通电时&#xff0c;处理器上运行的配置软件开始扫描PCIe总线以发现机器拓扑。…

Linux:线程的概念

线程&#xff1a;进程内的一个执行分支&#xff0c;他的执行粒度比进程要细 一、通过进程引入线程 以前我们想要一个执行流&#xff0c;我们需要fork一个子进程&#xff0c;然后子进程需要拷贝 take_struct结构体进程地址空间页表文件描述符表…… 而当我们只创建一个task_st…

跟着逻辑先生学习FPGA-实战篇第二课 6-2 LED灯流水灯实验

** 硬件平台&#xff1a;征战Pro开发板 软件平台&#xff1a;Vivado2018.3 仿真软件&#xff1a;Modelsim10.6d 文本编译器&#xff1a;Notepad** 征战Pro开发板资料 链接:https://pan.baidu.com/s/1AIcnaGBpNLgFT8GG1yC-cA?pwdx3u8 提取码:x3u8 1 知识背景 我们在《LED 灯…

Kafka数据迁移全解析:同集群和跨集群

文章目录 一、同集群迁移二、跨集群迁移 Kafka两种迁移场景&#xff0c;分别是同集群数据迁移、跨集群数据迁移。 一、同集群迁移 应用场景&#xff1a; broker 迁移 主要使用的场景是broker 上线,下线,或者扩容等.基于同一套zookeeper的操作。 实践&#xff1a; 将需要新添加…

Ashy的考研游记

文章目录 摘要12.1112.2012.21 DAY1&#xff08;政治/英语&#xff09;政治英语 12.22 DAY2&#xff08;数学/专业课&#xff09;数学专业课 结束估分 摘要 在24年的12月里&#xff0c;Ashy完成了他的考研冲刺&#xff0c;顺利的结束了他本年度的考研之旅。 在十二月里&#…

【Sentinel】流控效果与热点参数限流

目录 1.流控效果 1.1.warm up 2.2.排队等待 1.3.总结 2.热点参数限流 2.1.全局参数限流 2.2.热点参数限流 2.3.案例 1.流控效果 在流控的高级选项中&#xff0c;还有一个流控效果选项&#xff1a; 流控效果是指请求达到流控阈值时应该采取的措施&#xff0c;包括三种&…

【Unity3D】ECS入门学习(十二)IJob、IJobFor、IJobParallelFor

IJob&#xff1a;开启单个线程进行计算&#xff0c;线程内不允许对同一个数据进行操作&#xff0c;也就是如果你想用多个IJob分别计算&#xff0c;将其结果存储到同一个NativeArray<int>数组是不允许的&#xff0c;所以不要这样做&#xff0c;如下例子就是反面教材&#…

SELECT的使用

目录 1、SQL的查询命令 1.1 SELECT语句 1.2 投影查询 1.3 选择查询 1.4 聚合函数查询 1.5 简单分组查询(GROUP BY) 1.6 内连接查询 1.7 外连接查询 1.8 子查询 1. 无关子查询 2. 相关子查询 带exists的相关子查询&#xff1a; 1.9 集合查询 1. UNION(并) 2. INT…

电池均衡系统

一、电池概况 常见的电池分类&#xff1a;铅酸电池、锂电池、钠离子电池、碱性干电池、纽扣电池等&#xff0c;其中钠离子电池暂未大规模商用。 例如&#xff1a;电动车电池电压通常48v、60v、72v等&#xff0c;汽车启动电池电压&#xff1a;12v 而构成高电压的电池&#xf…

Windows系统下载、部署Node.js与npm环境的方法

本文介绍在Windows电脑中&#xff0c;下载、安装并配置Node.js环境与npm包管理工具的方法。 Node.js是一个基于Chrome V8引擎的JavaScript运行时环境&#xff0c;其允许开发者使用JavaScript编写命令行工具和服务器端脚本。而npm&#xff08;Node Package Manager&#xff09;则…