unity c# Tcp网络通讯

本篇附带源代码,带有处理拆包分包粘包,也会撰明具体内容。

首先对于tcp就是挥手机制,三次握手四次挥手机制。

一、三次握手

具体过程为简单解释为:

1、客户端请求服务器链接,等待服务器确认。(服务器如果确认请求,就会给这个客户端随机分配一个固定且唯一的ID号码)

2、服务器收到请求后,会向客户端发送应答,进行确认。(服务器会返回给你分配的id编码,代表下一次服务器希望收到以此为地址的固定的客户端序号,如果未来涉及断线重连这里也是非常重要的信息,要进行留存)

3、客户端收到信息后,会再次向服务器进行回复,发出确认。(就此服务器确认链接被确认,客户端服务器建立起链接)

【啰嗦一下:】

【握手为什么是三次?(防止已过期的链接请求报文突然又传输到服务器从而产生错误)、(三次才能确认双方接收和发送能力都正常)、(告知对方自己的初始序号值,并确认双方的序号值是否正确)以及(节省服务器性能【如果长时间服务器分配出id等待联接,会造成资源上的浪费,同时也可能被不法之人利用危害数据安全】)

为啥是三次不是四次?

已经可以确认链接了,无需第四次握手,浪费资源

更多可访问:详解 TCP 三次握手、四次挥手,附带精美图解和超高频面试题 - HYN的技术笔记 - SegmentFault 思否

二、四次挥手

即终止链接,这与tcp的机制有关,详细可看上面的链接。这里我们只做简略描述。

1、客户端发送关闭请求。

2、服务端收到后发回确认请求。

3、这个阶段下,服务器会发送最后的一些数据信息【这里面会有一些你没发完的一些数据信息,包括还未处理的内容信息】,最后会带一个结束的标识,代表服务器将这些没发完的内容发完了。

4、此时该服务器对此客户端的服务已经基本结束了,此时会发送最后的关闭信息。

5、客户端收到确认信息,再次发送确认信息,确认关闭,此时客户端自己就被关闭了,服务器在接受到指令后也就被关闭了。

这是基础内容,然后需要知道的是虽然tcp不会丢包,但是会有沾包的问题。

这个导致的问题有很多,可能是发送方造成的,也可能是接收方造成的。

1、发送方的tcp为提高传输效率,要收集到一定的数据后才可以发送,这就可能导致接受到原本是一大段的内容信息,可能是一段一段的。

2、mss规定,如果数据包过长就会被芬开传输,这样接收方就受到了粘包数据

3、接收方接收数据不及时,卡顿造成的

4、网络传输制式不统一【跨国业务中能遇到,甚至无法链接】

因此值得注意的是一般在unity开发过程中,并不太会使用tcp,一般在小游戏中往往会比较能够见到,相对来说kcp会更多,其次是http web【UnityWebRequest】(udp:往往信息传输的都是请求更新,更新完后的东西都会在本地处理一锤子买卖,干完就不认人【tps:有些境外赌博产品就是这么干的,id号就在本地保存,抓包一抓一个准】)

先上源代码吧,解析放在后面:

客户端 unity ,c#的也可根据这个改改就能用: 下面这个是核心部分

TcpClient
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Text;
using UnityEngine;public class Client
{static Client instance=new Client();public static Client Instance => instance;private TcpClient _client;public void Start(){_client = new TcpClient();Connect();}public async void Connect()//连接{try{//后端给的ip和服务器端口(这里暂时写的是本机ip)await _client.ConnectAsync("127.0.0.1",7788);Debug.Log("连接成功!");Receive();//连接}catch (System.Exception e){Console.WriteLine(e.Message);//打印错误}}public async void Send(byte[] data)//发送消息{try{await _client.GetStream().WriteAsync(data,0,data.Length);Debug.Log("发送成功!");}catch (Exception e){Debug.Log(e.Message);_client.Close();}}byte[] data = new byte[4096];int msgLenth = 0;//记录长度public async void Receive()//接收数据{try{while (_client.Connected){byte[] buff = new byte[4096];int lengh=await _client.GetStream().ReadAsync(buff,0,buff.Length);if (lengh>0){Debug.Log($"接收到数据了:{lengh}");MassengerHelper.Instance.CopyToData(buff,lengh);Debug.Log(Encoding.UTF8.GetString(buff,0,lengh));Array.Copy(buff, 0, data, msgLenth, lengh);//  JsonHelper.ToObject<JsonHelper.JsonTest>(buff);msgLenth += lengh;Handle();}else{_client.Close();}}}catch (Exception e){Debug.Log(e.Message);_client.Close();}}private void Handle(){//注意:这里只是举个例子,一般不会这么小,空间大小一般遵循二进制准则为1024//然后在这里我们对消息体进行封装,减少了传输,即:客户端和服务端都拿了一个密码本//双方约定传输内容,比如1,为登录,2为退出。。。//包体大小(4) 协议ID(4) 包体(byte[])if (msgLenth >= 8){byte[] _size = new byte[4];Array.Copy(data, 0, _size, 0, 4);int size = BitConverter.ToInt32(_size, 0);//本次要拿的长度var _length = 8 + size;if (msgLenth >= _length){//拿出idbyte[] _id = new byte[4];Array.Copy(data, 4, _id, 0, 4);int id = BitConverter.ToInt32(_id, 0);//包体byte[] body = new byte[size];Array.Copy(data, 8, body, 0, size);if (msgLenth > _length){for (int i = 0; i < msgLenth - _length; i++){data[i] = data[_length + i];}}msgLenth -= _length;Debug.Log($"收到客户端请求:{id}");}}}}

然后这里有个关联代码:

public class MassengerHelper
{private static MassengerHelper instance=new MassengerHelper();public static MassengerHelper Instance => instance;byte[] data = new byte[4096];int msgLenth = 0;public void CopyToData(byte[] buffer,int length){Array.Copy(buffer,0,data,msgLenth,length);msgLenth += length;Handle();}private void Handle(){//包体大小(4bit)协议(4)包体(byte[])if (msgLenth>=8) {byte[] _size = new byte[4];Array.Copy(data,0,_size,0,4);int size=BitConverter.ToInt32(_size,0);//获知包体具体大小//本次要拿的长度var _length = 8 + size;if (msgLenth>=_length) {//拿出idbyte[] _id = new byte[4];Array.Copy(data,4,_size,0,4);int id = BitConverter.ToInt32(_id,0);//包体byte[] body = new byte[size];Array.Copy(data,8,body,0,size);if (msgLenth>_length) {for (int i = 0; i < msgLenth-_length; i++){data[i] = data[_length];}}msgLenth -= _length;Debug.Log($"收到客户请求:{id}");//添加监听MessanagerCenter.Instance.Dispatch(id, body);}}}public void SendToSever(int id,string str){Debug.Log("ID"+id);var body = Encoding.UTF8.GetBytes(str);byte[] send_buff = new byte[body.Length+8];int size = body.Length;var _size = BitConverter.GetBytes(size);var _id = BitConverter.GetBytes(id);Array.Copy(_size,0,send_buff,0,4);Array.Copy(_id,0,send_buff,4,4);Array.Copy(body,0,send_buff,8,body.Length);Client.Instance.Send(send_buff);}
}

具体详细等我哪天有时间再更新吧,如果有错误欢迎大佬提出意见

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

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

相关文章

FileLink跨网数据摆渡系统:打破网络隔阂,轻松实现跨网络数据传输

在数字化时代&#xff0c;跨网络、跨区域的数据传输成为了企业和个人信息流通的重大挑战。而如今&#xff0c;FileLink跨网数据摆渡系统的问世&#xff0c;彻底解决了这一难题&#xff0c;帮助用户实现快速、安全、无缝的跨网络数据传输。 1. 跨网络数据传输的痛点 随着企业信…

高级 SQL 技巧详解

文章目录 高级 SQL 技巧详解一、引言二、窗口函数1、窗口函数的使用1.1、RANK() 函数示例1.2、常用窗口函数 三、公共表表达式&#xff08;CTE&#xff09;2、CTE 的使用2.1、CTE 示例 四、索引优化3、索引的创建与优化3.1、创建索引3.2、索引类型与注意事项 五、事务管理4、事…

MySQL_聚合函数分组查询

上篇复习&#xff1a; 设计数据库时的三大范式1.第一范式&#xff0c;一行数据中每一列不可再分 关系型数据库必须要满足第一范式&#xff0c;设计表的时候&#xff0c;如果每一列都可以用SQL规定的数据类型描述&#xff0c;就天然满足第一范式. 2.第二范式&#xff0c;在第一…

【Ai教程】Ollma安装 | 0代码本地运行Qwen大模型,保姆级教程来了!

我们平时使用的ChatGPT、kimi、豆包等Ai对话工具&#xff0c;其服务器都是部署在各家公司的机房里&#xff0c;如果我们有一些隐私数据发到对话中&#xff0c;很难保证信息是否安全等问题&#xff0c;如何在保证数据安全的情况下&#xff0c;又可以使用大预言模型&#xff0c;O…

FastAPI全方位分析:优劣尽显

近年来,随着技术的飞速发展,快速构建高性能API的需求越来越强烈。Python作为一个广泛使用的编程语言,也在这一领域下涌现出了许多优秀的框架。FastAPI便是其中一颗璀璨的新星。 FastAPI以其卓越的性能和独特的功能吸引了众多开发者。本文将深入剖析FastAPI的各个方面,详细…

LongVU :Meta AI 的解锁长视频理解模型,利用自适应时空压缩技术彻底改变视频理解方式

Meta AI在视频理解方面取得了令人瞩目的里程碑式成就&#xff0c;推出了LongVU&#xff0c;这是一种开创性的模型&#xff0c;能够理解以前对人工智能系统来说具有挑战性的长视频。 研究论文 "LongVU&#xff1a;用于长视频语言理解的时空自适应压缩 "提出了一种革命…

二分答案—愤怒的牛-P1676 [USACO05FEB] Aggressive cows G

[USACO05FEB] Aggressive cows G 题目描述 农夫约翰建造了一座有 n n n 间牛舍的小屋&#xff0c;牛舍排在一条直线上&#xff0c;第 i i i 间牛舍在 x i x_i xi​ 的位置&#xff0c;但是约翰的 m m m 头牛对小屋很不满意&#xff0c;因此经常互相攻击。约翰为了防止牛之…

什么是兼容性测试

兼容性测试&#xff0c;提供具有兼容性特性的云端设备&#xff08;覆盖主流品牌、SDK、分辨率&#xff09;&#xff0c;通过模拟用户行为进行真机测试。及时有效的发现应用中存在的兼容性问题。解除测试人员的双手&#xff0c;提高测试效率&#xff0c;保证产品在海量真机上的高…

IDEA:ctrl+/ 快捷键生成的注释,设置“//”开始位置

问题场景&#xff1a; IDEA中使用 ctrl/ 快捷键&#xff0c;//显示在最左边&#xff08;顶格&#xff09;&#xff0c;不美观&#xff0c;中间隔了好长的空格&#xff0c;如图&#xff1a; 解决方法: 操作步骤 File–>Sttings–>Editor–>Code Style–>Java–>…

中文文章进行加密编码及解码的方法python实现

愿我们终有重逢之时,而你还记得我们曾经讨论的话题。 group 868373192 second group 277356808 在Python中,可以使用多种方法对中文文章进行加密编码及解码。以下是几种常见的方法: 1. 使用Base64编码 Base64是一种基于64个可打印字符来表示二进制数据的编码方式。它可以…

掌握springboot过滤器,拦截器 ,aop

前言&#xff1a; Spring Boot 中的过滤器&#xff08;Filter&#xff09;、拦截器&#xff08;Interceptor&#xff09;和 AOP&#xff08;面向切面编程&#xff09;都是处理请求的常用技术&#xff0c;但它们在处理请求的时机、范围和方式上有所不同。下面详解分别介绍&#…

XLA中生成Causal Mask上三角-inf矩阵

transformers生成CausalAttentionMask的上三角-inf矩阵&#xff1a; 参考transformers源码 import torch import torch_xla import torch_xla.core.xla_model as xm import osos.environ[PJRT_DEVICE]IPU # os.environ[PJRT_DEVICE]GPU # os.environ[XLA_FLAGS]--xla_dump_tog…

IDEA2024下安装kubernetes插件并配置进行使用

【1】安装插件 其实2024.2.3下默认已经安装了kubernetes插件&#xff0c;如果你发现自己IDEA中没有&#xff0c;在市场里面检索并下载即可。 【2】kubernetes配置 ① 前置工作 首先你要准备一个config文件和一个kubectl.exe 。 config文件类似如下&#xff1a; apiVersi…

H7-TOOL的CAN/CANFD助手增加帧发送成功标识支持, 继续加强完善功能细节

2.27版本固件正式携带此功能&#xff0c;包括之前做的负载率检测和错误信息展示也将集成到这个版本固件中。 对于接收&#xff0c;我们可以直接看到效果&#xff0c;而发送不行&#xff0c;所以打算在发送的地方展示下发送成功标识。CAN发送不像串口&#xff0c;需要等待应答后…

微调LLM时,full、freeze、lora区别

LLama-Factory支持full、freeze、lora三种微调&#xff0c;区别&#xff1a; Full微调&#xff1a;Full微调是指在微调过程中更新整个模型的所有参数。这意味着所有的层和参数都会被更新&#xff0c;并且在微调期间都会参与训练。Full微调通常用于对模型进行全面的调整&#xf…

CSP/信奥赛C++刷题训练:经典广搜例题(4):洛谷P1746 :离开中山路

CSP/信奥赛C刷题训练&#xff1a;经典广搜例题&#xff08;4&#xff09;&#xff1a;洛谷P1746 &#xff1a;离开中山路 题目背景 《爱与愁的故事第三弹shopping》最终章。 题目描述 爱与愁大神买完东西后&#xff0c;打算坐车离开中山路。现在爱与愁大神在 x 1 , y 1 x_1…

CST汽车天线仿真(双向混合求解)

CST从2018版本开始具有双向混合求解&#xff0c;到2019版已经通用微波工作室的各个求解器之间的双向混合。具体的混合对象如下图&#xff1a; 对天线的安装和耦合仿真&#xff0c;意味着对复杂结构&#xff08;天线&#xff09;和电大尺寸环境&#xff08;安装平台&#xff0c;…

booleader的工作原理

Bootloader 的工作原理 在嵌入式系统中&#xff0c;Bootloader 是系统上电或复位时执行的第一个程序&#xff0c;它负责将嵌入式系统的主程序&#xff08;通常是操作系统或用户应用程序&#xff09;加载到内存中并启动运行。Bootloader 是嵌入式系统中的一个关键组件&#xff…

【鸿蒙】HarmonyOS NEXT应用开发快速入门教程之布局篇(下)

系列文章目录 【鸿蒙】HarmonyOS NEXT开发快速入门教程之ArkTS语法装饰器&#xff08;上&#xff09; 【鸿蒙】HarmonyOS NEXT开发快速入门教程之ArkTS语法装饰器&#xff08;下&#xff09; 【鸿蒙】HarmonyOS NEXT应用开发快速入门教程之布局篇&#xff08;上&#xff09; 【…

[Code]U-Mamba

U-MambaEnc-2d.py # 导入必要的模块 import torch import torch.nn as nn import torch.nn.functional as F# 定义一个上采样层类&#xff0c;继承自 nn.Module class UpsampleLayer(nn.Module):# 初始化方法&#xff0c;定义层的结构和所需的超参数def __init__(self, …