当前位置: 首页 > news >正文

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是可以跑通的。方便大家使用

相关文章:

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

兄弟们&#xff0c;我来填坑了&#xff0c;o(╥﹏╥)o o(╥﹏╥)o o(╥﹏╥)o o(╥﹏╥)o o(╥﹏╥)o o(╥﹏╥)o&#xff0c;前几天写了个tcp模拟websocket客户端的以为完成&#xff0c;后面需要发送消息给服务端&#xff0c;以为简单不就是一个发送消息么&#xff0c;这不是一…...

操作系统之同步与互斥的基本概念

1. 同步的基本概念 定义&#xff1a;同步是指在多个并发执行的进程或线程之间协调其行为&#xff0c;以使它们能够正确地相互合作。在计算机科学中&#xff0c;同步通常指对共享资源进行访问控制&#xff0c;以避免竞争条件和死锁等问题。 实现方式&#xff1a;为了实现同步&a…...

详细讲解axios封装与api接口封装管理

一、axios封装 axios是基于promise的http客户端&#xff0c;用于浏览器和nodejs发送http请求 &#xff0c;对它进行封装主要是为了统一管理请求配置和处理请求和响应的通用逻辑等。以下是常用的封装逻辑和要点 1&#xff1a;引入axios相关依赖 首先引用项目中的axios库&…...

API 接口如何确保数据的安全?

在API接口的对接中&#xff0c;确保数据的安全性是至关重要的。以下是一些关键措施&#xff0c;可以帮助实现这一目标&#xff1a; 一、认证与授权 API密钥&#xff1a;为每个调用方分配唯一的API密钥&#xff0c;客户端在请求时携带该密钥&#xff0c;服务器端验证其有效性。…...

HAL库STM32硬件IIC驱动数字电位器MCP4017

目录 一、芯片特性 二、硬件电路 三、工程搭建 四、IIC硬件地址 五、驱动程序 项目需要&#xff0c;最近用到了一个IIC接口的数字电位器&#xff0c;型号&#xff1a;MCP4017T-502E。对应阻值5K&#xff0c;使用STM32G030F6的硬件IIC驱动&#xff0c;发现简单的不得了&…...

「地平线」副总裁余轶南与「理想汽车」智驾产品总监赵哲伦联手创业,入局具身智能赛道!

小编早期文章&#xff1a;智驾领域从业者&#xff0c;疯狂涌入人形机器人赛道&#xff01;就有提到智驾领域从业者入局人形机器人赛道是趋势并分析原因。 之前媒体报道的智驾芯片上市公司【地平线】创始成员、副总裁、前软件平台产品线总裁余轶南&#xff08;博士&#xff09;…...

弹性盒子(display: flex)布局超全讲解|Flex 布局教程

文章目录 弹性盒子flex什么是弹性布局&#xff1f;弹性布局的特点&#xff1f;justify-contentalign-itemflex-direction (主轴的方向&#xff1a;水平或者垂直)flex-wrapflex-flowalign-contentflex-grow 属性flex-shrink 属性flex-basis 属性flex 属性align-self 属性 弹性盒…...

无问社区-无问AI模型

无问AI模型是无问社区新上线的一款AI功能&#xff0c;支持文本图像的输入&#xff0c;在文本理解能力、推理能力、视觉能力上相较于“社区助手”有了很大的提升。 我们在预训练模型的技术上增加1.7亿token的训练数据进行强化训练使其具备更好的效果。 更好的消息是我们准备了…...

如何记录日常笔记

如何使用Obsidian来记录日常的笔记吗&#xff1f;比如会议记录、读书笔记。 我认为&#xff0c;首先需要做好的就是建立一个单独的分类&#xff0c;比如设置会议记录的文件夹、读书笔记的文件夹&#xff0c;这样各个笔记相互不干扰。 而做日常记录&#xff0c;和我们进行卡片…...

【魅力golang】之-反射

1、引言 反射&#xff08;Reflection&#xff09;在 Golang中用于运行时检查和操作变量的类型和值。通过反射&#xff0c;可以实现动态类型处理&#xff0c;这在构建泛型代码、框架、序列化工具和动态代理等场景中非常有用。 2、什么是反射 反射是指程序在运行时能够动态地检…...

git--批量修改本地用户名和邮箱

原文网址&#xff1a;git--批量修改本地用户名和邮箱-CSDN博客 简介 本文介绍git如何批量修改项目的本地用户名和邮箱。 脚本 新建脚本&#xff1a;git_config.sh&#xff0c;内容如下&#xff1a; #!/bin/bash topDirpwd echo "开始处理" for file in ls ./ do…...

Rofin罗芬激光PowerLine L300 PL400 Manual 软件

Rofin罗芬激光PowerLine L300 PL400 Manual 软件...

【 thefuck 安装与使用】Linux 终端自动纠错工具:一头GitHub上的“草泥马“ - thefuck,妈妈再也不用担心我打错命令行了!

目录 快速安装使用 . 1.简介 2.安装 3.配置 4.补充 官方盗料参考 快速安装使用 快速安装使用&#xff0c;四步即可&#xff1a; #Ubuntu/Debian系统 sudo apt update sudo apt install python3-dev python3-pip sudo pip3 install thefuck #编辑bashrc配置文件 vim ~/.bashrc…...

牛客网刷题 ——C语言初阶——BC112小乐乐求和

1.牛客网刷题 ——C语言初阶 牛客网&#xff1a;BC112小乐乐求和 小乐乐最近接触了求和符号Σ&#xff0c;他想计算的结果。但是小乐乐很笨&#xff0c;请你帮助他解答。 输入描述: 输入一个正整数n (1 ≤ n ≤ 109) 输出描述: 输出一个值&#xff0c;为求和结果。 示例1 输…...

【PyTorch】(基础七)---- 完整训练流程

首先要明确一点&#xff0c;我们在编写模型、训练和使用模型的时候通常都是分开的&#xff0c;所以应该把Module的编写以及train方法和test方法分开编写。 调用gpu进行训练&#xff1a;在网络模型&#xff0c;数据&#xff0c;损失函数对象后面都使用.cuda&#xff08;&#x…...

01- 三自由度串联机械臂位置分析

三自由度串联机械臂如下图所示&#xff08;d180mm&#xff0c;L1100mm&#xff0c;L280mm&#xff09;&#xff0c;利用改进DH法建模&#xff0c;坐标系如下所示&#xff1a; 利用改进DH法建模&#xff0c;该机器人的DH参数表如下所示&#xff1a; 对该机械臂进行位置分析&…...

Flutter实现可拖拽操作Draggable

文章目录 1. Draggable 控件的构造函数主要参数&#xff1a; 2. Draggable 的工作原理3. 常见用法示例 1&#xff1a;基本的拖拽控件解释&#xff1a;示例 2&#xff1a;与 DragTarget 配合使用解释&#xff1a; 4. Draggable 的回调详解5. 总结 Draggable 是 Flutter 中一个用…...

Vue BPMN Modeler流程图

1、参考地址 git clone https://github.com/evanyangg/vue-bpmn-modeler.git 2、安装bpmn.js npm install bpmn-js --save 3、使用bpmn.js <template><div class"containers"><div class"canvas" ref"canvas"></div&g…...

写在公司40周年前夕

日子太快了&#xff0c;来这里工作六年多了。现在才知道原来入职的公司只是母公司的一小点。刚来一年就碰到疫情&#xff0c;三年疫情之后就迎来亏损&#xff0c;而后就是变了董事长&#xff0c;换了总经理。 这圣诞前&#xff0c;所有的子分又换了一把手。动作之大&#xff0c…...

Python调用Elasticsearch更新数据库

文章目录 Elasticsearch介绍Python调用Elasticsearch更新数据库 Elasticsearch介绍 Elasticsearch是一个基于Lucene的搜索引擎&#xff0c;它提供了一个分布式、多租户能力的全文搜索引擎&#xff0c;具有HTTP web接口和无模式的JSON文档。Elasticsearch是用Java开发的&#x…...

MVC 数据库

MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

vue3 字体颜色设置的多种方式

在Vue 3中设置字体颜色可以通过多种方式实现&#xff0c;这取决于你是想在组件内部直接设置&#xff0c;还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法&#xff1a; 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...

(二)原型模式

原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...

leetcodeSQL解题:3564. 季节性销售分析

leetcodeSQL解题&#xff1a;3564. 季节性销售分析 题目&#xff1a; 表&#xff1a;sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...

Unit 1 深度强化学习简介

Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库&#xff0c;例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体&#xff0c;比如 SnowballFight、Huggy the Do…...

Android15默认授权浮窗权限

我们经常有那种需求&#xff0c;客户需要定制的apk集成在ROM中&#xff0c;并且默认授予其【显示在其他应用的上层】权限&#xff0c;也就是我们常说的浮窗权限&#xff0c;那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...

GitHub 趋势日报 (2025年06月06日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...

论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing

Muffin 论文 现有方法 CRADLE 和 LEMON&#xff0c;依赖模型推理阶段输出进行差分测试&#xff0c;但在训练阶段是不可行的&#xff0c;因为训练阶段直到最后才有固定输出&#xff0c;中间过程是不断变化的。API 库覆盖低&#xff0c;因为各个 API 都是在各种具体场景下使用。…...

消防一体化安全管控平台:构建消防“一张图”和APP统一管理

在城市的某个角落&#xff0c;一场突如其来的火灾打破了平静。熊熊烈火迅速蔓延&#xff0c;滚滚浓烟弥漫开来&#xff0c;周围群众的生命财产安全受到严重威胁。就在这千钧一发之际&#xff0c;消防救援队伍迅速行动&#xff0c;而豪越科技消防一体化安全管控平台构建的消防“…...

华为云Flexus+DeepSeek征文 | 基于Dify构建具备联网搜索能力的知识库问答助手

华为云FlexusDeepSeek征文 | 基于Dify构建具备联网搜索能力的知识库问答助手 一、构建知识库问答助手引言二、构建知识库问答助手环境2.1 基于FlexusX实例的Dify平台2.2 基于MaaS的模型API商用服务 三、构建知识库问答助手实战3.1 配置Dify环境3.2 创建知识库问答助手3.3 使用知…...