UN2L4——区分消息类型
UN2L4——区分消息类型
不同类型的消息辨识问题
当将序列化的2进制数据发送给对象时,对方如何区分?举例:
PlayerInfo:玩家信息
ChatInfo:聊天信息
LoginInfo:登录信息
等等
这些数据对象序列化后是长度不同的字节数组,将它们发送给对象后,对方如何区分出他们分别是什么消息
如何选择对应的数据类反序列化它们?
区分消息思路
解决方案:为发送的信息添加标识,比如添加消息ID
在所有发送的消息的头部加上消息ID(int、short、byte、long都可以,根据实际情况选择)
举例说明:
消息构成,如果选用int类型作为消息ID的类型,前4个字节为消息ID,而后面的字节为数据类的内容
这样每次收到消息时,先把前4个字节取出来解析为消息ID,再根据ID进行消息反序列化即可
区分消息的关键点,是在数据字节数组头部加上消息ID,只要前后端定义好统一的规则
那么我们可以通过ID来决定如何反序列化消息,并且可以决定我们应该如何处理该消息
实现
实践步骤
创建消息基类,基类继承BaseData,基类添加获取消息ID的方法或者属性
让想要被发送的消 ...
UN2L3——Socket的TCP同步通信
UN2L3——Socket的TCP同步通信
服务端Socket的TCP同步通信
服务端Socket的基本思路如下:
创建套接字Socket
用Bind方法将套接字与本地地址绑定
用Listen方法监听
用Accept方法等待客户端连接
建立连接,Accept返回新套接字
对返回的新套接字用Send和Receive相关方法收发数据
用Shutdown方法释放连接
关闭套接字
根据以上思路,实现最基础的服务端代码
两台电脑在同一局域网下连接的实践
如果可以使用两台电脑并连接同一路由器,那么不妨将服务端代码中的IP地址改为在设备在路由器下的IP地址(在cmd使用ipconfig可查询)
并且客户端使用服务器的IP地址,如果可行,就可以实现客户端和服务端相互连接,使用两台设备学习的体会效果更好
游戏服务器一般使用8080作为自己的端口号
1234567891011121314151617181920212223242526272829303132333435363738394041static void Main(string[] args){ // ...
UN2L2——Socket的TCP通信概述
UN2L2——Socket的TCP通信概述
服务端和客户端代码编写大概思路
客户端
创建套接字Socket
用Connect方法与服务端相连
用Send和Receive相关方法收发数据
用Shutdown方法释放连接
关闭套接字
服务端
创建套接字Socket
用Bind方法将套接字与本地地址绑定
用Listen方法监听
用Accept方法等待客户端连接
建立连接,Accept返回新套接字
用Send和Receive相关方法收发数据
用Shutdown方法释放连接
关闭套接字
TCP协议三次握手的体现
TCP协议的三次握手被Socket封装在了内部,不需要我们进行额外处理
TCP协议四次挥手的体现
TCP协议的四次挥手被Socket封装在了内部,不需要我们进行额外处理
UN2L1——Socket的重要API
UN2L1——Socket的重要API
本章代码关键字
123456789101112131415161718192021222324252627282930313233343536373839System.Net.Sockets //Socket所在命名空间Socket //套接字类,用于网络通信AddressFamily //网络寻址枚举类型,决定寻址方案AddressFamily.InterNetwork //IPv4寻址AddressFamily.InterNetwork6 //IPv6寻址SocketType //套接字枚举类型,决定使用的套接字类型SocketType.Dgram //支持数据报,最大长度固定的无连接、不可靠的消息(主要用于UDP通信)SocketType.Stream //支持可靠、双向、基于连接的字节流 ...
UN1——网络开发理论和通信必备知识
UN1——网络开发理论和通信必备知识
前端程序网络开发需求
前端程序不需要像后端程序那样对网络通信、进程线程、数据库等知识进行更复杂的综合性应用
前端程序满足能对网络游戏开发中客户端网络模块中网络连接、网络通信、协议统一等必备需求即可
网络开发必备理论与知识
网络基本概念
IP、端口、Mac地址
客户端和服务端
数据通信模型
网络协议
网络协议概述
OSI 模型
TCP/IP 协议
TCP和UDP
通信前的必备知识
网络游戏通信方案概述
IP地址和端口类
域名解析
序列化和反序列化2进制数据
字节编码
序列化
反序列化
UN2——套接字Socket网络通信方案
UN2——套接字Socket网络通信方案
Socket
所谓套接字(Socket),就是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。
一个套接字就是网络上进程通信的一端,提供了应用层进程利用网络协议交换数据的机制。
从所处的地位来讲,套接字上联应用进程,下联网络协议栈,
是应用程序通过网络协议进行通信的接口,是应用程序与网络协议栈进行交互的接口
套接字_百度百科 (baidu.com)
它主要用于制作长连接游戏(强联网游戏)
本系列学习内容
Socket的重要API
TCP通信概述
同步
服务端和客户端的同步通信
区分消息类型
分包、黏包
客户端主动断开连接
实现心跳消息
异步
异步通信常用方法
服务端和客户端异步通信
UDP通信概述
服务端和客户端同步通信
异步通信常用方法
UN1L9-2——序列化和反序列化
UN1L9-2——序列化和反序列化
对于各类型数据和字节数据相互转换相关API,已在BitConverter讲过,这里一笔带过
序列化类对象
非字符串类型转字节数组
字节数组的长度,由该方法输入的数据类型决定,例如int就是4个字节,这个数组的长度就是4,存储了4个字节
这个方法可以转换大部分的基本数据类型,除了decimal和string,decimal我们几乎不用,而string我们使用Encoding类来转换
1byte[] bytes = BitConverter.GetBytes(99);
将字节数组转换为各种类型时,根据类型的不同,方法名是不同的,但是方法名的规律很简单,基本就是To + 类型或者To + Int + 位数
第一个参数填入要转换的字节数组,第二个参数填入要从数组第几个开始读取(默认为0)
12int i = BitConverter.ToInt32(bytes, 0);print(i);
字符串类型转字节数组
字符串 转换为 指定编码格式的字节数组 需要我们Encoding.编码格式.GetBytes(),一般在游戏开 ...
UN1L9-1——字节编码
UN1L9-1——字节编码
字符编码
字符编码(英语:Character encoding)也称字集码,
是把字符集中的字符,编码为指定集合中某一对象,以便文本在计算机中存储或通过网络进行传递。
说人话:
计算机里只能存数字(2机制),所以如果文字字符想要进行存储的话,就需要把对应的文字字符转换为数字才能进行处理,
而字符编码就是文字字符在计算机中和数值的对应关系,是人为定义的一种映射规则。
比如:
ASCII码(一种字符编码规则)中 数值65 用来映射 字符A,我们存储 A 这个字符,本质上存在内存中的是数值65对应的2进制是0100 0001
常见的一些字符编码规则有:
每个国家针对自己国家语言制定的编码规则(因为语言文字的数量各不相同)
ASCII码(美国)、GB2312编码(中国)、Shift_JIS编码(日本)、Euc-kr(韩国)等等
世界通用的编码规则(把所有语言统一到一套编码里)
Unicode编码,以及基于Unicode实现的编码规则:UTF-8、UTF-16、UTF-32
为何会出现乱码
很多人在查看文本文件时,经常会看到如下图中的这种乱码。那么为 ...
UN1L9——序列化和反序列化2进制数据
UN1L9——序列化和反序列化2进制数据
序列化和反序列化2进制数据
我们进行网络通信的目的是要传输数据,所以我们在正式学习网络通信之前,要先有二进制数据序列化和反序列化的知识储备
这样才能在讲解网络通信时,轻松应对数据收发相关的需求
网络通信中传输数据的序列化和反序列化是非常重要的,因此在讲解网络通信之前我们必须要掌握以下两个关键知识
将类对象序列化为2进制数据
将2进制数据反序列化为类对象
主要讲解的内容有:
字节编码
序列化
反序列化
网络通信中传输的数据
在网络通信中,我们把想要传递的类对象信息序列化为2进制数据(一般为byte字节数组),再将该2进制数据通过网络传输给远端设备
远端设备获取到该2进制数据后再将其反序列化为对应的类对象
回顾序列化和反序列化
序列化:将类对象信息转换为可保存或传输的格式的过程
反序列化:与序列化相对,将保存或传输过来的格式转换为类对象的过程
比如:
将C#类对象序列化为xml、json、2进制三种格式的数据保存在本地,达到持久化的目的,
再将保存在本地的持久化数据文件反序列化为C#类对象
回顾数据持久化2进制知识点
和网络通信相关的重 ...
UN1L8——域名解析
UN1L8——域名解析
本章代码关键字
12345678IPHostEntry //域名解析后的返回值,可以通过该对象获取IP地址、主机名等等信息,我们不会去自行new它ipHostEntry.AddressList //获取关联IPipHostEntry.Aliases //获取主机别名列表ipHostEntry.HostName //获取DNS名称Dns //Dns相关静态类,可以使用它来根据域名获取IP地址Dns.GetHostName() //获取本地系统的主机名Dns.GetHostEntry() //同步获取指定域名的IP信息Dns.GetHostEntryAsync() //异步获取指定域名的IP信息,返回一个Task协程类,await返回的task即可异步获取
域名解析
如果你不知道对方的IP地址,想通过域名和 ...