前期准备
- 创建工程和场景
- 把Server端的EncodeTools和NetMsg拖到Unity中
- 创建ClientPeer脚本,封装客户端的接收消息和发送消息
- 创建空物体NetMsgCenter用来挂载NetMsgCenter脚本,用来做消息处理中心
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using UnityEngine;
public class ClientPeer
{
private Socket clientSocket;
private NetMsg msg;
public ClientPeer()
{
try
{
msg = new NetMsg();
clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
}
catch (Exception e)
{
Debug.LogError(e.Message);
}
}
/// <summary>
/// 开始连接服务器
/// </summary>
public void Connect(string ip, int port)
{
try
{
clientSocket.Connect(new IPEndPoint(IPAddress.Parse(ip), port));
Debug.Log("连接服务器成功");
StartReceive();
}
catch (System.Exception e)
{
Debug.LogError(e.Message);
}
}
#region 接收消息
/// <summary>
/// 数据暂存区
/// </summary>
private byte[] receiveBuffer = new byte[1024];
/// <summary>
/// 数据缓存区
/// </summary>
private List<byte> receiveCache = new List<byte>();
/// <summary>
/// 存放消息队列
/// </summary>
private Queue<NetMsg> NetMsgsQueue = new Queue<NetMsg>();
/// <summary>
///是否正在处理接收的数据
/// </summary>
private bool isPeocessingReceive = false;
/// <summary>
/// 开始接收消息
/// </summary>
private void StartReceive()
{
if (clientSocket == null && clientSocket.Connected == false)
{
Debug.LogError("当前客户端未进行连接,接收消息失败!");
return;
}
clientSocket.BeginReceive(receiveBuffer, 0, 1024, SocketFlags.None, ReceiveCallBack, clientSocket);
}
/// <summary>
/// 开始接收完成后的回调函数
/// </summary>
private void ReceiveCallBack(IAsyncResult ar)
{
int length = clientSocket.EndReceive(ar);//得到接收到的长度
byte[] data = new byte[length];//接收容器,暂时用来保存接收到的数据
Buffer.BlockCopy(receiveBuffer, 0, data, 0, length);//把数据从数据缓存区拷贝到接收容器中
receiveCache.AddRange(data);//把接收到的数据添加到数据缓存区
if (isPeocessingReceive == false)
{
ProcessReceive();//调用处理数据的方法
}
StartReceive();//再次开始接收,伪递归
}
/// <summary>
/// 处理接收到的数据
/// </summary>
private void ProcessReceive()
{
isPeocessingReceive = true;
byte[] packet = EncodeTools.DecodePacket(ref receiveCache);//构造包,得到真正的数据,以前的数据加了包头
if (packet == null)
{
isPeocessingReceive = false;
return;
}
NetMsg msg = EncodeTools.DecodeMsg(packet);//把数据构造为NetMsg类
NetMsgsQueue.Enqueue(msg);//添加到存放消息的队列中,交给消息处理中心去处理
ProcessReceive();//再次处理,伪递归
}
#endregion
#region 接收消息
public void SendMsg(int opCode,int subCode,object value)
{
msg.Change(opCode, subCode, value);
SendMsg(msg);
}
public void SendMsg(NetMsg msg)
{
try
{
byte[] data = EncodeTools.EncodeMsg(msg);//把NetMsg类转换成byte[]
byte[] packet = EncodeTools.EncodePacket(data);//构造包,加上包头
clientSocket.Send(packet);
}
catch (Exception e)
{
Debug.LogError(e.Message);
}
}
#endregion
}
测试客户端与服务器的连接
客户端NetMsgCenter脚本(这里用来做测试)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NetMsgCenter : MonoBehaviour
{
private void Awake()
{
ClientPeer clientSocket = new ClientPeer();
clientSocket.Connect("127.0.0.1",6666);
}
}
Server端的设置
- 在GameServer的主程序入口中
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MyServer;
namespace GameServer
{
class Program
{
static void Main(string[] args)
{
SocketPeer serverSocket = new SocketPeer();
serverSocket.SetApplication(new NetMessageCenter());//设置应用层
serverSocket.StartServer("127.0.0.1",6666,100);
Console.ReadKey();
}
}
}
测试结果
有需要学习视频的欢迎关注微信公众号