unity3d 游戏服务器网络游戏 一般用什么服务器

Unity网络服务器搭建【中高级】 - 简书
<div class="fixed-btn note-fixed-download" data-toggle="popover" data-placement="left" data-html="true" data-trigger="hover" data-content=''>
写了16426字,被131人关注,获得了94个喜欢
Unity网络服务器搭建【中高级】
众所周知,网络游戏中,服务器的搭建尤为重要,无论是授权服务器,还是非授权服务器,它都承担着很大一部分的数据处理。今天,给大家分享一个中高级的小服务器搭建,当然也是在Unity上实现的,可以迁移为服务,外部程序等。其中加入了对象的序列化与反序列化,数据包的封包与拆包,细细品味,别有一番滋味。
服务器基础搭建
using UnityE
using System.C
using System.N
using System.Net.S
using System.Collections.G
using System.IO;
//实时消息处理委托
public delegate void NetEventHandler (string msg);
public class NetUtility
public static readonly NetUtility Instance = new NetUtility ();
//消息回调
private NetEventHandler ReceiveC
//服务器Tcp
private TcpListener tcpS
//客户端Tcp
private TcpClient tcpC
private byte[]
//缓存数据组
private List&byte&
//网络节点
private IPEndPoint serverIPEndP
/// &summary&
/// 设置网络节点
/// &/summary&
/// &param name="ep"&网络节点.&/param&
public void SetIpAddressAndPort (IPEndPoint ep)
//只写网络节点
serverIPEndPoint =
/// &summary&
/// 设置委托
/// &/summary&
/// &param name="handler"&消息委托.&/param&
public void SetDelegate (NetEventHandler handler)
//只写赋值回调
ReceiveCallback =
/// &summary&
/// Initializes a new instance of the &see cref="NetUtility"/& class.
/// &/summary&
private NetUtility ()
//服务器实例
tcpServer = new TcpListener (IPAddress.Any, 23456);
//客户端实例
tcpClient = new TcpClient (AddressFamily.InterNetwork);
//缓冲区初始化
buffer = new byte[1024];
//缓存数据组实例
cache = new List&byte& ();
//默认网络节点
serverIPEndPoint = new IPEndPoint (IPAddress.Parse ("127.0.0.1"), 23456);
服务器部分
#region Server Part:
/// &summary&
/// 开启服务器
/// &/summary&
public void ServerStart ()
//开启服务器
tcpServer.Start (10);
//服务器开启提示
ReceiveCallback ("Server Has Init!");
//开始异步接受客户端的连接请求
tcpServer.BeginAcceptTcpClient (AsyncAccept, null);
/// &summary&
/// 异步连接回调
/// &/summary&
/// &param name="ar"&Ar.&/param&
void AsyncAccept (System.IAsyncResult ar)
//接受到客户端的异步连接请求
tcpClient = tcpServer.EndAcceptTcpClient (ar);
//有新的客户端连接提示
ReceiveCallback ("Accept Client :" + tcpClient.Client.RemoteEndPoint.ToString ());
//异步接收消息
tcpClient.Client.BeginReceive (buffer, 0, 1024, SocketFlags.None, AsyncReceive, tcpClient.Client);
//异步接受客户端请求尾递归
tcpServer.BeginAcceptTcpClient (AsyncAccept, null);
/// &summary&
/// 异步接收消息回调
/// &/summary&
/// &param name="ar"&Ar.&/param&
void AsyncReceive (System.IAsyncResult ar)
//获取消息套接字
Socket workingClient = ar.AsyncState as S
//完成接收
int msgLength = workingClient.EndReceive (ar);
//如果接收到了数据
if (msgLength & 0) {
//消息接收提示
ReceiveCallback ("ReceiveData : " + msgLength + "bytes");
//临时缓冲区
byte[] tempBuffer = new byte[msgLength];
//拷贝数据到临时缓冲区
Buffer.BlockCopy (buffer, 0, tempBuffer, 0, msgLength);
//数据放到缓存数据组队尾
cache.AddRange (tempBuffer);
//拆包解析
byte[] result = LengthDecode (ref cache);
//如果已经接收完全部数据
if (result != null) {
//开始反序列化数据
NetModel resultModel = DeSerialize (result);
//TODO:Object Processing!
//数据对象结果提示
ReceiveCallback ("Object Result IP : " + resultModel.senderIp);
ReceiveCallback ("Object Result Content : " + resultModel.content);
ReceiveCallback ("Object Result Time : " + resultModel.time);
//消息未接收全,继续接收
tcpClient.Client.BeginReceive (buffer, 0, 1024, SocketFlags.None, AsyncReceive, tcpClient.Client);
#endregion
客户端部分
#region Client Part
/// &summary&
/// 客户端连接
/// &/summary&
public void ClientConnnect ()
//连接到服务器
tcpClient.Connect (serverIPEndPoint);
//连接到服务器提示
ReceiveCallback ("Has Connect To Server : " + serverIPEndPoint.Address.ToString ());
/// &summary&
/// 发送消息
/// &/summary&
/// &param name="model"&Model.&/param&
public void SendMsg (NetModel model)
//将数据对象序列化
buffer = Serialize (model);
//将序列化后的数据加字节头
buffer = LengthEncode (buffer);
//拆分数据,多次发送
for (int i = 0; i & buffer.Length/1024 + 1; i++) {
//满发送,1KB
int needSendBytes = 1024;
//最后一次发送,剩余字节
if (i == buffer.Length / 1024) {
//计算剩余字节
needSendBytes = buffer.Length - i * 1024;
//发送本次数据
tcpClient.GetStream ().Write (buffer, i * 1024, needSendBytes);
#endregion
#region Public Function
/// &summary&
/// 数据加字节头操作
/// &/summary&
/// &returns&数据结果.&/returns&
/// &param name="data"&源数据.&/param&
byte[] LengthEncode (byte[] data)
//内存流实例
using (MemoryStream ms = new MemoryStream()) {
//二进制流写操作实例
using (BinaryWriter bw = new BinaryWriter(ms)) {
//先写入字节长度
bw.Write (data.Length);
//再写入所有数据
bw.Write (data);
//临时结果
byte[] result = new byte[ms.Length];
//将写好的流数据放入临时结果
Buffer.BlockCopy (ms.GetBuffer (), 0, result, 0, (int)ms.Length);
//返回临时结果
/// &summary&
/// 数据解析,拆解字节头,获取数据.
/// &/summary&
/// &returns&源数据.&/returns&
/// &param name="cache"&缓存数据.&/param&
byte[] LengthDecode (ref List&byte& cache)
//如果字节数小于4,出现异常
if (cache.Count & 4)
//内存流实例
using (MemoryStream ms = new MemoryStream(cache.ToArray())) {
//二进制流读操作实例
using (BinaryReader br = new BinaryReader(ms)) {
//先读取数据长度,一个int值
int realMsgLength = br.ReadInt32 ();
//如果未接收全数据,下次继续接收
if (realMsgLength & ms.Length - ms.Position) {
//接收完,读取所有数据
byte[] result = br.ReadBytes (realMsgLength);
//清空缓存
cache.Clear ();
//返回结果
/// &summary&
/// 序列化数据.
/// &/summary&
/// &param name="mod"&数据对象.&/param&
private byte[] Serialize (NetModel mod)
//内存流实例
using (MemoryStream ms = new MemoryStream()) {
//ProtoBuf协议序列化数据对象
ProtoBuf.Serializer.Serialize&NetModel& (ms, mod);
//创建临时结果数组
byte[] result = new byte[ms.Length];
//调整游标位置为0
ms.Position = 0;
//开始读取,从0到尾
ms.Read (result, 0, result.Length);
//返回结果
} catch (Exception ex) {
Debug.Log ("Error:" + ex.ToString ());
/// &summary&
/// 反序列化数据.
/// &/summary&
/// &returns&数据对象.&/returns&
/// &param name="data"&源数据.&/param&
private NetModel DeSerialize (byte[] data)
//内存流实例
using (MemoryStream ms = new MemoryStream(data)) {
//调整游标位置
ms.Position = 0;
//ProtoBuf协议反序列化数据
NetModel mod = ProtoBuf.Serializer.Deserialize&NetModel& (ms);
//返回数据对象
} catch (Exception ex) {
Debug.Log ("Error: " + ex.ToString ());
#endregion
服务器实现
using UnityE
using System.C
using System.IO;
/// &summary&
/// 服务器实现.
/// &/summary&
public class ServerDemo : MonoBehaviour
//临时消息接收
string currentMsg = "";
Vector2 scrollViewP
void Start ()
scrollViewPosition = Vector2.
//消息委托
NetUtility.Instance.SetDelegate ((string msg) =& {
Debug.Log (msg);
currentMsg += msg + "\r\n";
//开启服务器
NetUtility.Instance.ServerStart ();
void OnGUI ()
scrollViewPosition = GUILayout.BeginScrollView (scrollViewPosition, GUILayout.Width (300), GUILayout.Height (300));
//消息展示
GUILayout.Label (currentMsg);
GUILayout.EndScrollView ();
客户端实现
using UnityE
using System.C
using System.T
/// &summary&
/// 客户端实现
/// &/summary&
public class ClientDemo : MonoBehaviour
//待解析地址
public string wwwAddress = "";
void Start ()
//消息处理
NetUtility.Instance.SetDelegate ((string msg) =& {
Debug.Log (msg + "\r\n");
//连接服务器
NetUtility.Instance.ClientConnnect ();
//开启协程
StartCoroutine (ServerStart ());
IEnumerator ServerStart ()
//加载网页数据
WWW www = new WWW (wwwAddress);
//编码获取内容
string content = UTF8Encoding.UTF8.GetString (www.bytes);
//内容测试
Debug.Log (content);
//待发送对象
NetModel nm = new NetModel ();
nm.senderIp = "127.0.0.1";
nm.content =
nm.time = DateTime.Now.ToString ();
//发送数据对象
NetUtility.Instance.SendMsg (nm);
Demo下载:链接:
密码: u36k
文中的ProtoBuf是跨平台的,可以跨平台传输对象。本文使用的是传输层的协议,有兴趣的同学可以使用网络层协议Socket实现,本文后续还会有网络游戏传输协议的内容,同学们随时关注。
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
被以下专题收入,发现更多相似内容:
提供高质量的Unity教程,供大家学习和参考
· 545人关注
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
选择支付方式:用 Unity 开发 MMO 类似的多人在线游戏使用什么样的网络方案? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
已注册用户请 &
Game Engines
用 Unity 开发 MMO 类似的多人在线游戏使用什么样的网络方案?
· 290 天前 · 3348 次点击
目前用的 Unity 5 ,内置的有 UNET ,看起来挺美好,对象状态的同步之类的都帮你做了
但是怎么看怎么像只适合局域网联机的游戏用,官方提供的 Internet Service 又让人觉得很虚,总不能把基础都交给别人吧
我现在的想法是按照 Unity 的 API ,以尽量兼容的方式写一个自己的框架出来,也得解决状态同步之类的事情,但是 UNET 封装的太严密了,反而没有 Unity4 的好加个 wrapper
有做游戏开发的同学可以分享一下网络联机的方案吗?
15 回复 &| &直到
21:33:27 +08:00
& &290 天前
服务器 bind 到一个地址 监听,
客户端 socket 连接
处理消息,同步状态,

& &290 天前
推荐去看 ue4 的官方文档和源码
& &290 天前
虽然帮不上才才什么忙,我还是可以来吹水的
& &290 天前
& &290 天前
& &290 天前
@ Unity 5 把老的比如 NetworkView 之类的都标为 deprecated 了,新的 High Level API 封的太死
看来自己重新写一套是最好的选择了,基础库还是逃不掉的
& &290 天前
虽然帮不上才才什么忙,我还是可以来吹水的
& &290 天前
虽然帮不上才才什么忙,我还是可以来吹水的.
& &290 天前
我使用的是 socket(System.Net) + 自定义协议+Google Protobuff ,服务器用 java 的 Netty ,完鸟。
从不用自己看不了或看不懂的库。
& &290 天前 via iPhone
噫你怎么开始做游戏了[doge]
我之前看到过一个手游,是 unity 里搞 websocket …
& &290 天前
给你一个关键词 unity photon
& &290 天前
@ 诡异的工作 2333 ,也是当玩啦
& &290 天前
@ 谢谢,这个 framework 看起来比 UNET 靠谱多了
& &285 天前
正好有 Unity5 的 demo
& &254 天前
普通 socket + Google Protobuff ,经历数个项目感觉稳定良好。
另推荐使用开元的 NF 服务器引擎,
目前引擎已在数个大型商业游戏使用过,有支持 unity 的客户端源码和网络库,稳定,高效的开发方法,正好满足你的需求。
& · & 1930 人在线 & 最高记录 2399 & · &
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.7.5 · 53ms · UTC 05:39 · PVG 13:39 · LAX 21:39 · JFK 00:39? Do have faith in what you're doing.

我要回帖

更多关于 unity3d网络游戏开发 的文章

 

随机推荐