尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
c#软件开发学习笔记--TCP 粘包拆包、SqlSugar 框架
学习总结TCP 粘包拆包 与 SqlSugar 框架一、TCP 粘包与拆包1.1 问题背景TCP 是面向字节流的协议发送方写入的数据在接收方看来是一条连续不断的字节流没有边界。因此会出现以下三种现象现象说明粘包多次发送的消息被合并成一次接收例如两条短消息挤在一个数据包中到达拆包一条消息被拆成多次接收例如大消息被网络层切成多个数据包混合既有粘包又有拆包同时发生注意粘包拆包不是 TCP 的 Bug而是字节流协议的固有特性。UDP 是面向报文的协议不存在此问题。1.2 常见解包方案消息定长每条消息固定长度不足补齐。特殊分隔符例如以\r\n结尾FTP、HTTP 头部采用此方式。头部长度字段本案例采用在消息体前加一个固定长度的头部记录消息体的字节长度。1.3 协议设计本案例本案例采用“4 字节头 变长消息体”的方案------------------------------- | Header | Body | | 4 bytes | N bytes | | (body长度) | (UTF8 文本) | -------------------------------头部4 字节整数存储消息体的字节长度字节序网络字节序大端使用IPAddress.HostToNetworkOrder/NetworkToHostOrder转换消息体UTF-8 编码的字符串1.4 关键代码1.4.1 编码消息 → 字节流/// summary/// 将字符串编码为「4字节长度头 消息体」的字节包/// /summaryprivatebyte[]EncodePackage(stringmsg){byte[]dataEncoding.UTF8.GetBytes(msg);// 将消息体长度转为网络字节序大端保证跨平台一致byte[]headLengthBitConverter.GetBytes(IPAddress.HostToNetworkOrder(data.Length));byte[]packagenewbyte[4data.Length];Array.Copy(headLength,package,headLength.Length);// 头部Array.Copy(data,0,package,4,data.Length);// 消息体returnpackage;}1.4.2 解码从字节流中循环抽取完整包/// summary/// 从缓冲区 bsList 中循环解析出完整消息/// 粘包一次能解析出多条拆包长度不足时跳出等待下次数据/// /summaryprivatevoidTryParsePackage(){while(bsList.Count4)// 至少要有 4 字节头部{byte[]headBytesbsList.GetRange(0,4).ToArray();intbodyLengthIPAddress.NetworkToHostOrder(BitConverter.ToInt32(headBytes,0));inttotalLength4bodyLength;if(bsList.CounttotalLength)break;// 拆包包不完整等下一次byte[]bodyDatabsList.GetRange(4,bodyLength).ToArray();stringmsgEncoding.UTF8.GetString(bodyData);AppendLog(收到消息msg);bsList.RemoveRange(0,totalLength);// 移除已解析部分继续解析下一个}}1.4.3 接收数据 缓冲/// summary/// 异步循环读取网络流累积到 bsList 后尝试解析/// /summaryprivatevoidReceiveData(TcpClientclient){ctsnewCancellationTokenSource();Task.Run(async(){byte[]buffernewbyte[1024];while(!cts.IsCancellationRequested){NetworkStreamstreamclient.GetStream();intlenawaitstream.ReadAsync(buffer,cts.Token);if(len0){AppendLog(客户端断开连接);break;}byte[]realDatanewbyte[len];Array.Copy(buffer,realData,len);bsList.AddRange(realData);// 关键累积到缓冲区TryParsePackage();}},cts.Token);}1.5 流程示意发送端 msg ──EncodePackage── [4字节头][body] ── stream.Write 接收端 stream.Read ── bsList.AddRange ── TryParsePackage (while循环) │ ┌─────────────┴─────────────┐ │ bsList.Count 4 ? │ │ 取出头部 → bodyLength │ │ 总长 4bodyLength │ │ 不足 → break (拆包等待) │ │ 足够 → 取body → 处理 → 移除 │ └───────────────────────────┘1.6 要点小结✅ 用Listbyte作为接收缓冲区累积所有到达字节✅ 用while循环解析一次可拆出多个包解决粘包✅ 包不完整时break等待下次数据解决拆包✅ 头部使用网络字节序保证收发双方字节序一致✅ 解析完一个包后必须RemoveRange移除已处理部分二、SqlSugar 第三方 ORM 框架2.1 框架简介SqlSugar是一款老牌国产 .NET ORM 框架由果糖大数据科技团队维护开箱即用、易于上手。2.2 两种使用模式模式类特点原生模式SqlSugarClient高性能每次 new 新对象禁止单例单例模式SqlSugarScope对新手友好解决大部分线程安全问题必须单例2.3 核心配置本案例采用原生模式/// summary/// 窗体加载时初始化 SqlSugarClient/// /summaryprivatevoidForm1_Load(objectsender,EventArgse){dbnewSqlSugarClient(newConnectionConfig(){ConnectionStringserver localhost,64345; database sugarDemo.db; uid sa; pwd 123123;EncryptTrue;TrustServerCertificateTrue,DbTypeDbType.SqlServer,IsAutoCloseConnectiontrue,// 自动关闭连接省去手动 using},db{// AOP执行 SQL 时打印原生 SQL方便调试db.Aop.OnLogExecuting(sql,pars){Console.WriteLine(UtilMethods.GetNativeSql(sql,pars));};});}2.4 实体定义[SugarTable]// 标记为数据库表publicclassStudent{[SugarColumn(IsPrimaryKeytrue,IsIdentitytrue)]// 主键 自增publicintId{get;set;}publicstringName{get;set;}publicint?Age{get;set;}// 可空类型对应数据库可空字段}2.5 数据库与表初始化// 创建数据库若不存在db.DbMaintenance.CreateDatabase();// CodeFirst根据实体类自动生成/同步表结构db.CodeFirst.InitTables(typeof(Student));2.6 核心 APICRUD操作API示例增db.InsertableT(entity).ExecuteCommand()db.Insertable(list).ExecuteCommand()删db.DeleteableT(entity).ExecuteCommand()db.DeleteableStudent(stu).ExecuteCommand()改db.UpdateableT(entity).ExecuteCommand()db.UpdateableStudent(stu).ExecuteCommand()查db.QueryableT()...ToList()db.QueryableStudent().Single(s s.Id id)2.6.1 批量插入ListStudentlistnewListStudent(){newStudent(){Name张三1,Age100},newStudent(){Name张三2,Age200},newStudent(){Name张三3,Age300},};introwdb.Insertable(list).ExecuteCommand();2.6.2 条件查询 动态拼接使用ExpressionableT动态拼接 where 条件避免写大量 if-else 分支 SQL。/// summary/// 根据界面输入条件动态拼接查询条件并分页绑定 DataGridView/// /summaryprivatevoidBindView(){if(dbnull)return;varexpressExpressionable.CreateStudent();// AndIF仅当条件成立时追加 AND 过滤express.AndIF(!string.IsNullOrWhiteSpace(textBox1.Text),ss.Name.Contains(textBox1.Text));express.AndIF(!string.IsNullOrWhiteSpace(textBox2.Text),ss.Ageint.Parse(textBox2.Text));express.AndIF(!string.IsNullOrWhiteSpace(textBox3.Text),ss.Ageint.Parse(textBox3.Text));varlistdb.QueryableStudent().Where(express.ToExpression()).ToPageList(pageNumber,pageSize,reftotalCount,reftotalPages).ToList();dataGridView1.DataSourcelist;label2.Text${pageNumber}/{totalPages};}2.6.3 修改与删除按主键定位// 修改先查后改intidint.Parse(dataGridView1.SelectedRows[0].Cells[Id].Value!.ToString()!);Studentstudb.QueryableStudent().Single(ss.Idid);stu.Name三生三世;stu.Age100;db.UpdateableStudent(stu).ExecuteCommand();// 删除Studentstudb.QueryableStudent().Single(ss.Idid);db.DeleteableStudent(stu).ExecuteCommand();2.7 分页查询要点ToPageList(pageNumber, pageSize, ref totalCount, ref totalPages)一次返回当前页数据 总数 总页数翻页只需修改pageNumber后重新调用BindView()每页条数变更时应重置pageNumber 1避免越界2.8 要点小结✅IsAutoCloseConnection true让连接管理自动化避免资源泄漏✅Aop.OnLogExecuting是调试 SQL 的利器✅ExpressionableT适合动态条件查询场景✅CodeFirst.InitTables实现代码先行实体变更直接同步表结构✅ CRUD 全部链式调用统一以ExecuteCommand()增删改或ToList()/Single()查收尾三、关联知识点ADO.NET 五大对象SqlConnection、SqlCommand、SqlDataAdapter、SqlDataReader、DataSetSqlSugar 底层即基于此封装。IOC / DISqlSugarClient 推荐使用 Scope 或瞬发注入禁止单例。网络字节序TCP 自定义协议应统一使用大端序HostToNetworkOrder/NetworkToHostOrder。
RELATED

相关推荐

如何批量实现抖音视频下载无水印?我的实测记录与避坑指南

如何批量实现抖音视频下载无水印?我的实测记录与避坑指南

如何批量实现抖音视频下载无水印?我的实测记录与避坑指南 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback su…

📅 2026/10/12 19:07:05
基于ESP32与FOC控制的自主越野载具:硬件架构与软件实现

基于ESP32与FOC控制的自主越野载具:硬件架构与软件实现

1. 项目缘起:为什么我们需要一台“全地形自主RDS载具”? 在机器人、自动化物流和特种作业领域,我们常常面临一个经典难题:如何让一个移动平台在非结构化的、崎岖不平的野外环境中,稳定、可靠且自主地执行运输或作业任务…

📅 2026/9/25 11:30:45
【毕设作品】基于Flask的游戏推荐系统的设计与实现

【毕设作品】基于Flask的游戏推荐系统的设计与实现

文章目录前言题目技术栈功能概述实现页面截图系统测试系统测试目的系统功能测试系统测试结论文章参考我的优势数据库参考源码获取前言 ❤️博主简介:全网累计学员1000,培训机构讲师、全栈开发工程师、知乎/小红书优秀作者、腾讯云/阿里云VIP客户、专注Ja…

📅 2026/9/27 17:41:28
MORE NEWS

更多资讯

📰

Python机器学习人脸识别系统:从期末大作业到门禁机实战

简介:这份资源是面向高校学生与Python初学者的机器学习人脸识别系统完整项目包,可直接用于期末大作业、课程设计或自学练手。压缩包共4个文件,包含2个py源码文件、1份pdf报告文档和1份md说明文件,整体约631KB,体积轻便…

📰

基于Python的单通道脑电睡眠分期:从数据到模型全流程实战

简介:这是一套面向计算机相关专业学生与项目实战学习者的单通道脑电信号自动睡眠分期研究资料,源自经导师指导并通过评审的高分毕业设计,适合作为毕设参考、课程设计或期末大作业。资源围绕单通道脑电信号展开,涵盖数据预处理、模…

📰

Python机器学习实战:从环境配置到模型训练复现的完整流程

简介:《Python机器学习编程与实战》配套源代码与实验数据压缩包,面向从零起步的机器学习初学者和高校教学场景,旨在通过实际代码与数据集,帮助读者把NumPy、Pandas、Matplotlib、sklearn等库的操作落到真实案例中。包内共77个文件…

📰

供应链断裂与重构测度:基于Python的级联失效与替代路径实现

简介:针对《经济研究》2024年第8期丁浩员等提出的跨国供应链断裂与重构测度方法,这份Python代码包给出了从数据清洗到指标计算的完整复现路径。资源面向经济学研究者、供应链分析人员及数据科学从业者,基于FactSet Revere全球供应链数据库&am…

📰

Python车牌识别计费系统实战:从OCR识别到状态机与跨天计费

简介:面向需要构建智能停车管理系统的 Python 开发者、计算机专业学生以及毕业设计人员,这份源码包提供了一套从车牌识别、车辆入场出场判断、收入统计到满预警的完整可运行方案,并可在 PyCharm 中直接运行,借助百度 AI 开放平台的…

📰

南开编译原理作业实战:简单C语言编译器源码解析与避坑指南

简介:这份资源是南开大学软件学院编译原理课程的作业成果,包含一个可运行的简单C语言编译器完整源码与配套文档,面向计算机、人工智能、通信工程等专业的在校学生及教师,也适合作为课程设计、毕业设计或自学编译原理的参考范例。压…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬