修改一 因为现在要接受的类型是类对象类型,所以需要将队列中的接收类型进行更换
在之前的NetMgr中将
public Queue<string> sendMsgQueue = new Queue<string>();
public Queue<string> receiveQueue = new Queue<string>();
修改成
public Queue<BaseMsg> sendMsgQueue = new Queue<BaseMsg>();
public Queue<BaseMsg> receiveQueue = new Queue<BaseMsg>();
修改2 发送消息的修改
在SendMeg()中将之前的socket.Send(Encoding.UTF8.GetBytes(sendMsgQueue.DEQueue()));
修改成
socket.Send(sendMsgQueue.Dequeue().Writing());
修改3 接受消息的修改
//将反序列化的字符串 放容器中
receiveQueue.Enqueue(Encoding.UTF8.GetString(receiveBytes,0,receiveNum))
改成
先获取消息ID int msgID=BitConverter.ToInt32(receiveBytes, 0)
BaseMsg baseMsg = null
然后用Switch去判断消息ID
switch (msgID)
{
case 1001:
PlayerMsg msg = new PlayerMsg()
msg.Reading(receiveBytes, 4)
baseMsg = msg
break
if (baseMsg == null) continue
receiveQueue.Enqueue(baseMsg)
}
修改4 打印消息的修改
消息的打印是放在Update中的
修改成
BaseMsg msg= receiveQueue.Dequeue();
if(msg is PlayerMsg)
{
PlayerMsg playerMsg = (PlayerMsg)msg;
print(playerMsg.playerID);
print(playerMsg.playerData.name);
print(playerMsg.playerData.atk);
print(playerMsg.playerData.lev);
}
代码如下
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using UnityEngine;
using UnityEngine.UI;
public class NetMgr1 : MonoBehaviour
{
//单例模式
public static NetMgr1 instance;
public static NetMgr1 Instance=>instance;
private bool isConnected = false; //是否连接到服务器的开关
//因为可以接收结构类消息 所以 使用BaseMsg
//创建一个队列 用来存储要发送的消息
public Queue<BaseMsg> sendMsgQueue = new Queue<BaseMsg>();
//创建一个队列 用来存储要接收的消息
public Queue<BaseMsg> receiveQueue = new Queue<BaseMsg>();
//接收消息的容器
byte[] receiveBytes = new byte[1024*1024];
int receiveNum;
Socket socket;
private void Awake()
{
instance = this;
}
private void Update()
{
if (receiveQueue.Count > 0)
{
//print(receiveQueue.Dequeue());
//取出消息
BaseMsg msg= receiveQueue.Dequeue();
//需要进行判断是哪个结构类
if(msg is PlayerMsg)
{
PlayerMsg playerMsg = (PlayerMsg)msg;
print(playerMsg.playerID);
print(playerMsg.playerData.name);
print(playerMsg.playerData.atk);
print(playerMsg.playerData.lev);
}
}
}
//连接服务器 传入IP和端口号
public void Connect(string host, int port)
{
//1.判断是否是连接状态 如果是 就返回
if (isConnected)
return;
//设置连接方式
socket=new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//获取服务器的 IPEndPoint
IPEndPoint ipPoint = new IPEndPoint(IPAddress.Parse(host), port); //里面输入服务器的IP和端口号
try
{
socket.Connect(ipPoint); //连接 成功
//Send("连接成功");
//进行收发消息
//用线程池进行嗲用
ThreadPool.QueueUserWorkItem(SendMsg);
ThreadPool.QueueUserWorkItem(receiveMsg);
}
catch(SocketException e)
{
if (e.ErrorCode == 10061)
{
print("服务器拒绝连接");
}
else
{
print("连接服务器失败" + e.ErrorCode);
}
return;
}
}
/// <summary>
/// 发送消息 外部
/// </summary>
/// <param name="info"></param>
public void Send(BaseMsg msg)
{
sendMsgQueue.Enqueue(msg);
}
public void SendMsg(object obj)
{
while (!isConnected)
{
if(sendMsgQueue.Count > 0)
{
//socket.Send(Encoding.UTF8.GetBytes(sendMsgQueue.Dequeue()));
//序列化
socket.Send(sendMsgQueue.Dequeue().Writing());
}
}
}
/// <summary>
/// 不停的接收消息
/// </summary>
private void receiveMsg(object obj)
{
while (!isConnected)
{
if (socket.Available > 0)
{
//获取长度
receiveNum = socket.Receive(receiveBytes);
//解析
// receiveQueue.Enqueue(Encoding.UTF8.GetString(receiveBytes,0,receiveNum));
//因为是可以接受结构类 所以首先要获取他的消息ID
int msgID = BitConverter.ToInt32(receiveBytes, 0);
BaseMsg baseMsg = null; //临时接收
switch (msgID)
{
case 1001:
PlayerMsg msg = new PlayerMsg();
msg.Reading(receiveBytes, 4); //前面的整型是消息ID 所以从4开始
//解析出来的数据放在Update中打印 所以需要放在接受队列中
baseMsg = msg;
break;
}
//如果消息为空 那就是不支持的类型 ,没有解析
if (baseMsg == null)
continue;
//收到消息 放入公共容器
receiveQueue.Enqueue(baseMsg);
}
}
}
public void Close()
{
if(socket != null)
{
socket.Shutdown(SocketShutdown.Both);
socket.Close();
//关闭接收和发送服务
isConnected = false;
}
}
private void OnDestroy()
{
Close();
}
}