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

C++Socket通讯样例(服务端)

1. 创建Socket实例并开启。

private int OpenTcp(int port, string ip = "")
{//1. 开启服务端try{_tcpServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);IPAddress ipAddr = IPAddress.Any;if (ip != "" && ip != string.Empty){ipAddr = IPAddress.Parse(ip);}_tcpServer.Bind(new IPEndPoint(ipAddr, port));_tcpServer.Listen();_isListening = true;//开启线程Thread listenThread = new Thread(new ThreadStart(AcceptClients));listenThread.Start();}catch (Exception ex){Log.Instance.Error("TcpServer setup fail!\n" + CommonMsg.Space + ex.Message);}return 0;
}

2. 客户端连接——AcceptClients实现。

private void AcceptClients()
{while (_isListening){//单客户端_tcpSocket = _tcpServer.Accept();if (_tcpSocket != null){Thread clientThread = new Thread(SocketReceive);clientThread.Start(_tcpSocket);Log.Instance.Info($"Socket connected!  ( {_tcpSocket.LocalEndPoint} )");}Thread.Sleep(300);}
}

3. 接收客户端信息——SocketReceive实现。

(仅仅将接收的数据放到队列中,不加处理,否则可能耗时而影响通讯接收)

private void SocketReceive(object? obj)
{Socket? tcpClient = (Socket?)obj;if (tcpClient == null) return;//以下代码不放入线程中while (true){if (tcpClient.Connected){int available = tcpClient.Available;if (available > 0){byte[] buffer = new byte[available];int dataSize = tcpClient.Receive(buffer);if (dataSize != available) { MessageBox.Show("Socket received data not equal to available data"); break; }_queueMsgRecv.Enqueue(buffer);}}Thread.Sleep(5);}tcpClient.Close();
}

4. 开启数据处理线程——OpenMsgParseThread

(不断从接收队列中取数据,根据通讯协议进行解析,并处理)

private void OpenMsgParseThread()      
{Task.Run(() =>{while (true){while (_queueMsgRecv.TryDequeue(out byte[]? buffer)){if (buffer != null && buffer.Length > 0){//查询list 中是否存在结束符while (true){List<byte> bufList = buffer.ToList();int flagIdx = bufList.IndexOf(0x04);if (flagIdx == -1){//不存在结束符_msgValid += Encoding.UTF8.GetString(buffer);break;}else{//存在结束符_msgValid += Encoding.UTF8.GetString(buffer.Take(flagIdx).ToArray());buffer = buffer.Skip(flagIdx + 1).Take(buffer.Length - flagIdx - 1).ToArray();try{JObject jObj = JObject.Parse(_msgValid);  //这个地方 如果发来的数据格式有问题,或者不完整,解析会出现异常ProcessRecvMsg(jObj);}catch (Exception ex){Log.Instance.Error("Msg: " + _msgValid);_msgValid = "";byte[] data = LeadlapTool.CreateComnData(MsgToken.TcpDataParseException, null, false, ex.Message);SendMsg(data);continue;}_msgValid = "";continue;}}}}Thread.Sleep(5);}});
}

5. 开启数据发送线程——OpenMsgSendThread

(不断从发送队列取数据,执行发送)

private void OpenMsgSendThread()
{Task.Run(() =>{while (true){if (_tcpSocket.Connected){lock (_locker){bool ret = _queueMsgSend.TryDequeue(out byte[]? data);if (ret && data != null){_tcpSocket.Send(data);}}}Thread.Sleep(10);}});
}

6. 在需要发送数据处执行发送操作——SendMsg

lock (_locker)
{_queueMsgSend.Enqueue(data);
}

7. 关于数据解析

通常需要约定好帧头、帧尾,防止数据丢包、粘包情况。

(1)描述:数据为 byte[],以 0x04 为结束符。

(2)分析:如果数据发送由于阻塞,导致粘包;或者如果发送数据量过大,分好几次才接收完整,导致拆包;

(3)解决:粘包——对数据包解析识别结束符 0x04 并分割,分别解析。

拆包——对数据包叠加,直至识别到结束符 0x04,整合后解析。

(4)数据类型转换。

0x04 作为 byte比较。用 List 的 IndexOf 函数判断,若是-1,则不存在;否则返回 序号。

byte[] --> List: buffer.ToList();

List --> byte[]: bufList.ToArray();

byte[] --> string: Encoding.UTF8.GetString(buffer);

string --> byte[]: Encoding.UTF8.GetBytes(msg);

buffer.Take(flagIdx).ToArray();

相关文章:

C++Socket通讯样例(服务端)

1. 创建Socket实例并开启。 private int OpenTcp(int port, string ip "") {//1. 开启服务端try{_tcpServer new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);IPAddress ipAddr IPAddress.Any;if (ip ! "" && i…...

【学术会议论文投稿】大数据治理:解锁数据价值,引领未来创新

第六届国际科技创新学术交流大会&#xff08;IAECST 2024&#xff09;_艾思科蓝_学术一站式服务平台 更多学术会议请看&#xff1a;https://ais.cn/u/nuyAF3 目录 引言 一、大数据治理的定义 二、大数据治理的重要性 三、大数据治理的核心组件 四、大数据治理的实践案例…...

location中href和replace的区别

1.有两种方式&#xff1a; a、使用 location.href&#xff1a;window.location.href“success.html”; b、使用location.replace&#xff1a;window.location.replace(“new_file.html”); 2.区别是什么&#xff1f; 结果&#xff1a;href相当于打开一个新页面&#xff0c;…...

基于Spring Boot的在线摄影工作室开发指南

1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及&#xff0c;互联网成为人们查找信息的重要场所&#xff0c;二十一世纪是信息的时代&#xff0c;所以信息的管理显得特别重要。因此&#xff0c;使用计算机来管理网上摄影工作室的相关信息成为必然。开发合…...

JDK源码系列(五)—— ConcurrentHashMap + CAS 原理解析

更好的阅读体验 \huge{\color{red}{更好的阅读体验}} 更好的阅读体验 ConcurrentHashMap 类 ConcurrentHashMap 1.7 在JDK1.7中ConcurrentHashMap采用了数组分段锁的方式实现。 Segment(分段锁)-减少锁的粒度 ConcurrentHashMap中的分段锁称为Segment&#xff0c;它即类似于…...

技术成神之路:二十三种设计模式(导航页)

设计原则/模式链接面向对象的六大设计原则技术成神之路&#xff1a;面向对象的六大设计原则创建型模式单例模式建造者模式原型模式工厂方法模式抽象工厂模式行为型模式策略模式状态模式责任链模式观察者模式备忘录模式迭代器模式模板方法模式访问者模式中介者模式命令模式解释器…...

Rust编程与项目实战-元组

【图书介绍】《Rust编程与项目实战》-CSDN博客 《Rust编程与项目实战》(朱文伟&#xff0c;李建英)【摘要 书评 试读】- 京东图书 (jd.com) Rust编程与项目实战_夏天又到了的博客-CSDN博客 8.2.1 元组的定义 元组是Rust的内置复合数据类型。Rust支持元组&#xff0c;而且元…...

容性串扰和感性串扰

串扰根源在于耦合&#xff0c;电场耦合产生容性耦合电流&#xff0c;磁场耦合产生感性耦合电流 关于容性后向串扰电压与后向串扰系数推导...

windows Terminal 闪退 -- 捣蛋砖家

最近点击Windows 终端总是闪退。 日志提示: 错误应用程序名称: WindowsTerminal.exe&#xff0c;版本: 1.21.2410.17001&#xff0c;时间戳: 0x67118f02 错误模块名称: ucrtbase.dll&#xff0c;版本: 10.0.22621.3593&#xff0c;时间戳: 0x10c46e71 异常代码: 0xc0000409 错…...

java-web-day5

1.spring-boot-web入门 目标: 开始最基本的web应用的构建 使用浏览器访问后端, 后端给浏览器返回HelloController 流程: 1.创建springboot工程, 填写模块信息, 并勾选web开发的相关依赖 注意: 在新版idea中模块创建时java下拉框只能选17, 21, 23 这里选17, maven版本是3.6.3, 很…...

Python | Leetcode Python题解之第508题出现次数最多的子树元素和

题目&#xff1a; 题解&#xff1a; class Solution:def findFrequentTreeSum(self, root: TreeNode) -> List[int]:cnt Counter()def dfs(node: TreeNode) -> int:if node is None:return 0sum node.val dfs(node.left) dfs(node.right)cnt[sum] 1return sumdfs(r…...

Java 分布式缓存

在当今的大规模分布式系统中&#xff0c;缓存技术扮演着至关重要的角色。Java 作为一种广泛应用的编程语言&#xff0c;拥有丰富的工具和框架来实现分布式缓存。本文将深入探讨 Java 分布式缓存的概念、优势、常见技术以及实际应用案例&#xff0c;帮助读者更好地理解和应用这一…...

【MySQL】MySQL 使用全教程

MySQL 使用全教程 介绍 MySQL 是一种广泛使用的开源关系型数据库管理系统(Relational Database Management System)&#xff0c;它基于 Structured Query Language&#xff08;SQL&#xff09;进行数据管理&#xff0c;允许用户存储、检索、更新和删除数据库中的数据。通过提供…...

油猴脚本-GPT问题导航侧边栏增强版

为 GPT官网和相关网站提供了一个便捷的侧边栏目录&#xff0c;能够自动搜集当前会话页面的问题&#xff0c;展示在侧边栏上&#xff0c;可快速导航到问题的位置。 安装使用地址:https://scriptcat.org/zh-CN/script-show-page/1972 安装前请确保浏览器有油猴&#xff0c;没有…...

Java Lock ConditionObject 总结

前言 相关系列 《Java & Lock & 目录》&#xff08;持续更新&#xff09;《Java & Lock & ConditionObject & 源码》&#xff08;学习过程/多有漏误/仅作参考/不再更新&#xff09;《Java & Lock & ConditionObject & 总结》&#xff08;学习…...

模块化主动隔振系统市场规模:2023年全球市场规模大约为220.54百万美元

模块化主动隔振系统是一种用于精密设备和实验装置的隔振解决方案&#xff0c;通过主动控制技术消除振动干扰&#xff0c;提供稳定的环境。目前&#xff0c;随着微纳制造和精密测量技术的发展&#xff0c;对隔振系统的要求越来越高。模块化设计使得系统能够灵活适应不同负载和工…...

SpringAOP:对于同一个切入点,不同切面不同通知的执行顺序

目录 1. 问题描述2. 结论结论1&#xff1a;"对于同一个切入点&#xff0c;同一个切面不同类型的通知的执行顺序"结论2&#xff1a;"对于同一个切入点&#xff0c;不同切面不同类型通知的执行顺序" 3. 测试环境&#xff1a;SpringBoot 2.3.4.RELEASE测试集合…...

unique_ptr初始化

std::unique_ptr 是 C11 引入的智能指针&#xff0c;用于管理动态分配的对象的生命周期。unique_ptr 确保每个动态分配的对象有且仅有一个所有者&#xff0c;当 unique_ptr 超出作用域时&#xff0c;它会自动释放其管理的对象。以下是 std::unique_ptr 的一些常见初始化方法。 …...

HelloCTF [RCE-labs] Level 8 - 文件描述和重定向

开启靶场&#xff0c;打开链接&#xff1a; GET传参cmd system($cmd.">/dev/null 2>&1"); 这行代码将执行命令 $cmd&#xff0c;并且将其标准输出和标准错误输出都重定向到 /dev/null&#xff0c;这意味着无论命令的输出还是可能产生的错误信息都不会显示…...

DEVOPS: 集群伸缩原理

概述 阿里云 K8S 集群的一个重要特性&#xff0c;是集群的节点可以动态的增加或减少有了这个特性&#xff0c;集群才能在计算资源不足的情况下扩容新的节点&#xff0c;同时也可以在资源利用 率降低的时候&#xff0c;释放节点以节省费用理解实现原理&#xff0c;在遇到问题的…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…...

golang循环变量捕获问题​​

在 Go 语言中&#xff0c;当在循环中启动协程&#xff08;goroutine&#xff09;时&#xff0c;如果在协程闭包中直接引用循环变量&#xff0c;可能会遇到一个常见的陷阱 - ​​循环变量捕获问题​​。让我详细解释一下&#xff1a; 问题背景 看这个代码片段&#xff1a; fo…...

学校招生小程序源码介绍

基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码&#xff0c;专为学校招生场景量身打造&#xff0c;功能实用且操作便捷。 从技术架构来看&#xff0c;ThinkPHP提供稳定可靠的后台服务&#xff0c;FastAdmin加速开发流程&#xff0c;UniApp则保障小程序在多端有良好的兼…...

在四层代理中还原真实客户端ngx_stream_realip_module

一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡&#xff08;如 HAProxy、AWS NLB、阿里 SLB&#xff09;发起上游连接时&#xff0c;将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后&#xff0c;ngx_stream_realip_module 从中提取原始信息…...

1.3 VSCode安装与环境配置

进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件&#xff0c;然后打开终端&#xff0c;进入下载文件夹&#xff0c;键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作

一、上下文切换 即使单核CPU也可以进行多线程执行代码&#xff0c;CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短&#xff0c;所以CPU会不断地切换线程执行&#xff0c;从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

(一)单例模式

一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...

Vite中定义@软链接

在webpack中可以直接通过符号表示src路径&#xff0c;但是vite中默认不可以。 如何实现&#xff1a; vite中提供了resolve.alias&#xff1a;通过别名在指向一个具体的路径 在vite.config.js中 import { join } from pathexport default defineConfig({plugins: [vue()],//…...

vue3 daterange正则踩坑

<el-form-item label"空置时间" prop"vacantTime"> <el-date-picker v-model"form.vacantTime" type"daterange" start-placeholder"开始日期" end-placeholder"结束日期" clearable :editable"fal…...