其实写过多次网络链接。但是因为换了工作,又没电脑在身边,所以以前的代码都没办法翻出来用。

所以从今天起,一些常用的代码只好放到网上。

公司有一个局域网的游戏。本来想用u3d的rpc就可以完成。但是后来说要传语音。于是只有写一个tcp。

目前完成的模块大的说就两块,网络和消息分发。

服务器有玩家池的管理。

网络部分没有想得很详细。因为是局域网,所以也不存在多大开销。如果有需要上千的需求,可能还要优化下代码结构以及锁。

有缘之人自取。

无论你干什么,我都没任何要求。唯一的要求,如果你发现有bug,或者什么地方改改更好,请告诉我。谢谢!

socket部分

 using System.Net.Sockets;
using System.Net;
using System.Threading;
using UnityEngine;
using System.Collections.Generic;
/*
*轻量级局域网服务器。
* 协议如下
* 消息头前2字节保存当前消息长度
* 后面跟4字节表示消息ID
* 再后面是消息实质内容
*/ namespace LanSocket
{
class ClientConnect
{
public byte[] m_AllData;
public int m_AllDataHead;
public int m_AllDataEnd;
public int m_MsgCount;
public byte[] m_OnePack;
public int m_OnePackIndex;
public Socket m_Connect;
public long m_UserID; public ClientConnect()
{
m_AllData = new byte[LanSocketBase.m_MaxAllBuff];
m_AllDataHead = ;
m_AllDataEnd = ;
m_MsgCount = ;
m_OnePack = new byte[LanSocketBase.m_MaxOnePackBuff];
m_OnePackIndex = ;
m_Connect = null;
m_UserID = ;
} public void Reset()
{
m_AllDataHead = ;
m_AllDataEnd = ;
m_MsgCount = ;
m_OnePackIndex = ;
m_Connect = null;
m_UserID = ;
}
}
class Server : LanSocketBase
{
static Queue<int> m_MsgOrder; static Socket m_ServerSocket;
static Thread m_LinstenThread;
static Thread m_ReciveThread;
static System.Collections.ArrayList m_ServerSocketList;
static System.Collections.ArrayList m_listenSocketList;
static System.Collections.ArrayList m_DeleteSocketList;
static int m_MaxClientConnect = ;
static ClientConnect[] m_ConnectPool;
static Queue<int> m_EmptyConnect;
public static void Start()
{
if (m_HasInit)
{
return;
}
string mLocalIP = ""; string mHostName = Dns.GetHostName();
IPHostEntry localHost = Dns.GetHostEntry(mHostName);
for (int i = ; i < localHost.AddressList.Length; ++i)
{
if (localHost.AddressList[i].AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
{
MonoBehaviour.print(localHost.AddressList[i].ToString());
mLocalIP = localHost.AddressList[i].ToString();
break;
}
} if ("".Equals(mLocalIP))
{
MonoBehaviour.print("网络检测异常。请检查网络设置或接入网络");
return;
}
LanSocketBase.BaseInit();
m_MsgOrder = new Queue<int>(); //服务器IP地址
IPAddress ip = IPAddress.Parse(mLocalIP);
m_ServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
m_ServerSocket.Bind(new IPEndPoint(ip, )); //绑定IP地址:端口
m_ServerSocket.Listen(); //设定最多10个排队连接请求
MonoBehaviour.print("启动监听" + m_ServerSocket.LocalEndPoint.ToString() + "成功"); m_ServerSocketList = new System.Collections.ArrayList();
m_listenSocketList = new System.Collections.ArrayList();
m_DeleteSocketList = new System.Collections.ArrayList(); m_ConnectPool = new ClientConnect[m_MaxClientConnect];
m_EmptyConnect = new Queue<int>();
for (int i = ; i < m_MaxClientConnect; ++i)
{
m_ConnectPool[i] = new ClientConnect();
m_EmptyConnect.Enqueue(i);
}
//通过Clientsoket发送数据
m_ReciveThread = new Thread(ReceiveMessage);
m_ReciveThread.Start();
m_LinstenThread = new Thread(ListenClientConnect);
m_LinstenThread.Start();
} /// <summary>
/// 监听客户端连接
/// </summary>
public static void ListenClientConnect()
{
while (true)
{
Thread.Sleep();
m_ServerSocketList.Add(m_ServerSocket);
Socket.Select(m_ServerSocketList, null, null, );
for (int i = ; i < m_ServerSocketList.Count; ++i)
{
Socket clientSocket = ((Socket)m_ServerSocketList[i]).Accept();
if (null != clientSocket)
{
try
{
Lock();
if ( == m_EmptyConnect.Count)
{
MonoBehaviour.print("链接已经达到最大上线,丢弃当前连接");
clientSocket.Shutdown(SocketShutdown.Both);
clientSocket.Close();
}
else
{
//m_listenSocketList.Add(clientSocket);
int mSlot = m_EmptyConnect.Dequeue();
m_ConnectPool[mSlot].m_Connect = clientSocket;
m_ConnectPool[mSlot].m_UserID = System.DateTime.Now.ToFileTime();
MonoBehaviour.print("成功连接一个客户端,编号:" + mSlot.ToString());
}
}
finally
{
UnLock();
}
}
}
m_ServerSocketList.Clear();
}
} private static bool PutDataToBuff(byte[] mClientSendBuff, int mReceiveNumber, Socket client)
{
ClientConnect curPlayer = null;
int mSlot = -;
for (int i = ; i < m_MaxClientConnect; ++i)
{
if (client == m_ConnectPool[i].m_Connect)
{
curPlayer = m_ConnectPool[i];
mSlot = i;
break;
}
}
if (null == curPlayer)
{
return false;
}
if (curPlayer.m_AllDataEnd + mReceiveNumber >= LanSocketBase.m_MaxAllBuff)
{
byte[] mCurAllData = new byte[curPlayer.m_AllDataEnd - curPlayer.m_AllDataHead];
System.Buffer.BlockCopy(curPlayer.m_AllData, curPlayer.m_AllDataHead, mCurAllData, , curPlayer.m_AllDataEnd - curPlayer.m_AllDataHead);
System.Buffer.BlockCopy(mCurAllData, , curPlayer.m_AllData, , curPlayer.m_AllDataEnd - curPlayer.m_AllDataHead);
curPlayer.m_AllDataEnd -= curPlayer.m_AllDataHead;
curPlayer.m_AllDataHead = ;
}
int mOnePackStartPos = ;
while (mReceiveNumber > )
{
if ( == m_OnePackIndex)
{
ushort datalen = System.BitConverter.ToUInt16(mClientSendBuff, mOnePackStartPos);
if (datalen > LanSocketBase.m_MaxOnePackBuff || datalen < LanSocketBase.m_HeadSize)
{
return false;
}
if (datalen <= mReceiveNumber)
{
System.Buffer.BlockCopy(mClientSendBuff, mOnePackStartPos, curPlayer.m_AllData, curPlayer.m_AllDataEnd, datalen);
curPlayer.m_AllDataEnd += datalen;
mOnePackStartPos += datalen; mReceiveNumber -= datalen; m_MsgOrder.Enqueue(mSlot);
}
else
{
System.Buffer.BlockCopy(mClientSendBuff, mOnePackStartPos, m_OnePack, m_OnePackIndex, mReceiveNumber);
m_OnePackIndex += mReceiveNumber;
mOnePackStartPos += mReceiveNumber; mReceiveNumber -= mReceiveNumber;
}
}
else
{
ushort datalen = System.BitConverter.ToUInt16(m_OnePack, );
if (datalen > LanSocketBase.m_MaxOnePackBuff || datalen < LanSocketBase.m_HeadSize)
{
return false;
}
if (m_OnePackIndex + mReceiveNumber >= datalen)
{
int mNeedNum = datalen - m_OnePackIndex;
System.Buffer.BlockCopy(mClientSendBuff, mOnePackStartPos, m_OnePack, m_OnePackIndex, mNeedNum);
mOnePackStartPos += mNeedNum; System.Buffer.BlockCopy(m_OnePack, , curPlayer.m_AllData, curPlayer.m_AllDataEnd, datalen);
m_OnePackIndex = ; mReceiveNumber -= mNeedNum; m_MsgOrder.Enqueue(mSlot);
}
else
{
System.Buffer.BlockCopy(mClientSendBuff, mOnePackStartPos, m_OnePack, m_OnePackIndex, mReceiveNumber);
m_OnePackIndex += mReceiveNumber;
mOnePackStartPos += mReceiveNumber; mReceiveNumber -= mReceiveNumber;
}
}
} return true;
} /// <summary>
/// 接收消息
/// </summary>
public static void ReceiveMessage()
{
try
{
while (true)
{
Thread.Sleep();
for (int i = ; i < m_MaxClientConnect; ++i)
{
if (null != m_ConnectPool[i].m_Connect)
{
m_listenSocketList.Add(m_ConnectPool[i].m_Connect);
}
}
if ( == m_listenSocketList.Count)
{
continue;
}
Socket.Select(m_listenSocketList, null, null, );
for (int i = ; i < m_listenSocketList.Count; ++i)
{
Socket mClient = (Socket)m_listenSocketList[i];
//try
//{
//通过clientSocket接收数据
byte[] mClientSendBuff = new byte[m_MaxOnePackBuff];
int mReceiveNumber = mClient.Receive(mClientSendBuff);
if ( == mReceiveNumber)
{
m_DeleteSocketList.Add(mClient);
}
else if (mReceiveNumber > )
{
try
{
Lock();
bool rt = PutDataToBuff(mClientSendBuff, mReceiveNumber, mClient);
if (!rt)
{
m_DeleteSocketList.Add(mClient);
}
}
catch (System.Exception ex)
{
MonoBehaviour.print("PutDataToBuff catch: " + ex.Message);
}
finally
{
UnLock();
}
}
else
{
MonoBehaviour.print("one connect recive a error num: " + mReceiveNumber.ToString());
}
//}
//catch (System.Exception ex)
//{
// MonoBehaviour.print("ReceiveMessage catch: " + ex.Message);
// m_DeleteSocketList.Add(mClient);
//}
}
m_listenSocketList.Clear();
if ( != m_DeleteSocketList.Count)
{
ShutDownConnect();
}
} }
catch (System.Exception ex)
{
MonoBehaviour.print("ReceiveMessage out:" + ex.Message);
} } /// <summary>
/// 程序退出销毁
/// </summary>
public static void Destroy()
{
if (!m_HasInit)
{
return;
}
m_LinstenThread.Abort();
m_ReciveThread.Abort();
m_listenSocketList.Clear(); for (int i = ; i < m_ServerSocketList.Count; ++i)
{
Socket mServer = (Socket)m_ServerSocketList[i];
if (mServer.Connected)
{
mServer.Shutdown(SocketShutdown.Both);
}
mServer.Close();
}
m_ServerSocketList.Clear(); for (int i = ; i < m_MaxClientConnect; ++i)
{
if (null != m_ConnectPool[i].m_Connect)
{
if (m_ConnectPool[i].m_Connect.Connected)
{
m_ConnectPool[i].m_Connect.Shutdown(SocketShutdown.Both);
}
m_ConnectPool[i].m_Connect.Close();
m_ConnectPool[i].m_Connect = null;
}
}
m_EmptyConnect.Clear();
LanSocketBase.BaseRelease();
} /// <summary>
/// 销毁一个连接
/// </summary>
static void ShutDownConnect()
{
try
{
Lock();
for (int j = ; j < m_DeleteSocketList.Count; ++j)
{
Socket connect = (Socket)m_DeleteSocketList[j];
for (int i = ; i < m_MaxClientConnect; ++i)
{
if (connect == m_ConnectPool[i].m_Connect)
{
connect.Shutdown(SocketShutdown.Both);
connect.Close();
m_ConnectPool[i].Reset();
m_EmptyConnect.Enqueue(i);
MonoBehaviour.print("关闭一个连接,编号:" + i.ToString());
break;
}
}
}
}
catch (System.Exception ex)
{
MonoBehaviour.print("ShutDownConnect catch: " + ex.Message);
}
finally
{
m_DeleteSocketList.Clear();
UnLock();
}
} /// <summary>
/// 获取一个数据
/// </summary>
public static void GetMsg(ref ClientMsgUnPack msg)
{
try
{
Lock();
if ( != m_MsgOrder.Count)
{
int mSlot = m_MsgOrder.Dequeue();
ClientConnect curPlayer = m_ConnectPool[mSlot];
ushort mOnePackLen = System.BitConverter.ToUInt16(curPlayer.m_AllData, curPlayer.m_AllDataHead);
msg = new ClientMsgUnPack(curPlayer.m_AllData, (ushort)curPlayer.m_AllDataHead, (ushort)mOnePackLen, mSlot);
msg.SetUserID(curPlayer.m_UserID);
curPlayer.m_AllDataHead += mOnePackLen;
}
}
finally
{
UnLock();
}
} public static void SendTo(ref MsgPack msg, long userID)
{
try
{
Lock();
for(int i = ; i < m_MaxClientConnect ; ++i)
{
ClientConnect curPlayer = m_ConnectPool[i];
if (null != curPlayer.m_Connect && curPlayer.m_UserID == userID)
{
curPlayer.m_Connect.Send(msg.GetByte(), msg.GetByteLen(), SocketFlags.None);
break;
}
}
}
finally
{
UnLock();
}
} public static void SendToAll(ref MsgPack msg)
{
try
{
Lock();
for (int i = ; i < m_MaxClientConnect; ++i)
{
ClientConnect curPlayer = m_ConnectPool[i];
if (null != curPlayer.m_Connect)
{
curPlayer.m_Connect.Send(msg.GetByte(), msg.GetByteLen(), SocketFlags.None);
break;
}
}
}
finally
{
UnLock();
}
}
}
}

SocketServer.cs

 using System.Net.Sockets;
using System.Net;
using System.Threading;
using UnityEngine;
using System.Collections.Generic; /*
*轻量级局域网服务器。
* 协议如下
* 消息头前2字节保存当前消息长度
* 后面跟4字节表示消息ID
* 再后面是消息实质内容
*/ namespace LanSocket
{
class Client : LanSocketBase
{
static Thread m_ReciveThread;
static Socket m_Connect;
static byte[] m_AllData;
static int m_AllDataHead;
static int m_AllDataEnd;
static int m_MsgNum; public static void Start()
{
if (m_HasInit)
{
return;
}
//设定服务器IP地址
IPAddress ip = IPAddress.Parse("192.168.1.109");
Socket temp = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
temp.Connect(new IPEndPoint(ip, )); //配置服务器IP与端口
MonoBehaviour.print("连接服务器成功"); LanSocketBase.BaseInit();
m_Connect = temp;
m_ReciveThread = new Thread(ReceiveMessage);
m_ReciveThread.Start();
m_AllData = new byte[LanSocketBase.m_MaxAllBuff + ];
m_AllDataHead = ;
m_AllDataEnd = ;
m_MsgNum = ;
}
catch
{
MonoBehaviour.print("连接服务器失败");
return;
}
} private static void PutDataToBuff(byte[] mClientSendBuff, int mReceiveNumber)
{
if (m_AllDataEnd + mReceiveNumber >= LanSocketBase.m_MaxAllBuff)
{
byte[] mCurAllData = new byte[m_AllDataEnd - m_AllDataHead];
System.Buffer.BlockCopy(m_AllData, m_AllDataHead, mCurAllData, , m_AllDataEnd - m_AllDataHead);
System.Buffer.BlockCopy(mCurAllData, , m_AllData, , m_AllDataEnd - m_AllDataHead);
m_AllDataEnd -= m_AllDataHead;
m_AllDataHead = ;
}
int mOnePackStartPos = ;
while (mReceiveNumber > )
{
if ( == m_OnePackIndex)
{
ushort datalen = System.BitConverter.ToUInt16(mClientSendBuff, mOnePackStartPos);
if (datalen <= mReceiveNumber)
{
System.Buffer.BlockCopy(mClientSendBuff, mOnePackStartPos, m_AllData, m_AllDataEnd, datalen);
m_AllDataEnd += datalen; mOnePackStartPos += datalen; mReceiveNumber -= datalen;
++m_MsgNum;
}
else
{
System.Buffer.BlockCopy(mClientSendBuff, mOnePackStartPos, m_OnePack, m_OnePackIndex, mReceiveNumber);
m_OnePackIndex += mReceiveNumber;
mOnePackStartPos += mReceiveNumber; mReceiveNumber -= mReceiveNumber;
}
}
else
{
ushort datalen = System.BitConverter.ToUInt16(m_OnePack, );
if (m_OnePackIndex + mReceiveNumber >= datalen)
{
int mNeedNum = datalen - m_OnePackIndex;
System.Buffer.BlockCopy(mClientSendBuff, mOnePackStartPos, m_OnePack, m_OnePackIndex, mNeedNum);
mOnePackStartPos += mNeedNum; System.Buffer.BlockCopy(m_OnePack, , m_AllData, m_AllDataEnd, datalen);
m_OnePackIndex = ; mReceiveNumber -= mNeedNum;
}
else
{
System.Buffer.BlockCopy(mClientSendBuff, mOnePackStartPos, m_OnePack, m_OnePackIndex, mReceiveNumber);
m_OnePackIndex += mReceiveNumber;
mOnePackStartPos += mReceiveNumber; mReceiveNumber -= mReceiveNumber;
}
}
}
} public static void Destroy()
{
if (!m_HasInit)
{
return;
}
LanSocketBase.BaseRelease();
ShutDownConnect();
m_MsgNum = ;
} public static void GetMsg(ref MsgUnPack msg)
{
if (!m_HasInit)
{
return;
}
try
{
Lock();
if ( != m_MsgNum)
{
ushort datalen = System.BitConverter.ToUInt16(m_AllData, m_AllDataHead);
msg = new MsgUnPack(m_AllData, (ushort)m_AllDataHead, (ushort)datalen);
m_AllDataHead += datalen;
--m_MsgNum;
}
}
finally
{
UnLock();
}
} /// <summary>
/// 接收消息
/// </summary>
public static void ReceiveMessage()
{
while (true)
{
Thread.Sleep();
try
{
//通过clientSocket接收数据
byte[] mClientSendBuff = new byte[m_MaxOnePackBuff + ];
int mReceiveNumber = m_Connect.Receive(mClientSendBuff);
if ( == mReceiveNumber)
{
MonoBehaviour.print("disconnect");
ShutDownConnect();
}
else if (mReceiveNumber > )
{
try
{
Lock();
PutDataToBuff(mClientSendBuff, mReceiveNumber);
}
catch (System.Exception ex)
{
MonoBehaviour.print("PutDataToBuff catch: " + ex.Message);
}
finally
{
UnLock();
}
}
else
{
MonoBehaviour.print("one connect recive a error num: " + mReceiveNumber.ToString());
}
}
catch (System.Exception ex)
{
MonoBehaviour.print("ReceiveMessage catch: " + ex.Message);
ShutDownConnect();
}
}
} public static void Send(ref MsgPack msg)
{
try
{
Lock();
m_Connect.Send(msg.GetByte(), msg.GetByteLen(), SocketFlags.None);
}
finally
{
UnLock();
}
} public static void ShutDownConnect()
{
m_ReciveThread.Abort();
if (m_Connect.Connected)
{
m_Connect.Shutdown(SocketShutdown.Both);
}
m_Connect.Close();
}
}
}

SocketClient.cs

支持类部分

 using System.Threading;
using UnityEngine; /*
*轻量级局域网服务器。
* 协议如下
* 消息头前2字节保存当前消息长度
* 后面跟4字节表示消息ID
* 再后面是消息实质内容
*/ namespace LanSocket
{
public class LanSocketBase
{
public static int m_MaxOnePackBuff = * ;
public static int m_MaxAllBuff = * ;
public static int m_HeadSize = ;
protected static bool m_HasInit = false;
protected static byte[] m_OnePack;
protected static int m_OnePackIndex;
private static Mutex m_Mutex; public static void BaseInit()
{
m_HasInit = true;
m_Mutex = new Mutex();
m_OnePack = new byte[m_MaxOnePackBuff+];
m_OnePackIndex = ;
} public static void BaseRelease()
{
m_Mutex.Close();
} protected static void Lock()
{
m_Mutex.WaitOne();
//MonoBehaviour.print("Lock:" + Thread.CurrentThread.ManagedThreadId.ToString());
} protected static void UnLock()
{
m_Mutex.ReleaseMutex();
//MonoBehaviour.print("Unlock:" + Thread.CurrentThread.ManagedThreadId.ToString());
}
}
}

LanSocketBase

 using System.Threading;

 /*
*轻量级局域网服务器。
* 协议如下
* 消息头前2字节保存当前消息长度
* 后面跟4字节表示消息ID
* 再后面是消息实质内容
*/ namespace LanSocket
{
public class PackBase
{
protected int m_MaxOnePackBuff;
protected byte[] m_OnePack;
protected int m_OnePackIndex; public PackBase()
{
m_MaxOnePackBuff = LanSocketBase.m_MaxOnePackBuff;
m_OnePack = new byte[m_MaxOnePackBuff];
m_OnePackIndex = ;
}
}
}

PackBase.cs

 using UnityEngine;
/*
* 通信协议
* 消息头前2字节保存当前消息长度
* 后面跟4字节表示消息ID
* 再后面是消息实质内容
*/ namespace LanSocket
{
class MsgPack : PackBase
{
public MsgPack()
{
m_OnePackIndex = LanSocketBase.m_HeadSize;
} public void SetHead(int ID)
{
byte[] mBuff = System.BitConverter.GetBytes(ID);
System.Buffer.BlockCopy(mBuff, , m_OnePack, , );
} public void PackEnd()
{
byte[] mBuff = System.BitConverter.GetBytes(m_OnePackIndex);
System.Buffer.BlockCopy(mBuff, , m_OnePack, , );
} public void Packbool(bool data)
{
ushort curDatalen = ;
if (m_OnePackIndex + curDatalen > m_MaxOnePackBuff)
{
MonoBehaviour.print("Packbool() longer lager than Max buff len");
return;
}
byte[] mBuff = System.BitConverter.GetBytes(data);
Pack(mBuff, curDatalen);
} public void Pack16bit(short data)
{
ushort curDatalen = ;
if (m_OnePackIndex + curDatalen > m_MaxOnePackBuff)
{
MonoBehaviour.print("Pack16bit(short) longer lager than Max buff len");
return;
}
byte[] mBuff = System.BitConverter.GetBytes(data);
Pack(mBuff, curDatalen);
}
public void Pack16bit(ushort data)
{
ushort curDatalen = ;
if (m_OnePackIndex + curDatalen > m_MaxOnePackBuff)
{
MonoBehaviour.print("Pack16bit(ushort) longer lager than Max buff len");
return;
}
byte[] mBuff = System.BitConverter.GetBytes(data);
Pack(mBuff, curDatalen);
}
public void Pack32bit(int data)
{
ushort curDatalen = ;
if (m_OnePackIndex + curDatalen > m_MaxOnePackBuff)
{
MonoBehaviour.print("Pack32bit(int) longer lager than Max buff len");
return;
}
byte[] mBuff = System.BitConverter.GetBytes(data);
Pack(mBuff, curDatalen);
}
public void Pack32bit(uint data)
{
ushort curDatalen = ;
if (m_OnePackIndex + curDatalen > m_MaxOnePackBuff)
{
MonoBehaviour.print("Pack32bit(uint) longer lager than Max buff len");
return;
}
byte[] mBuff = System.BitConverter.GetBytes(data);
Pack(mBuff, curDatalen);
}
public void Pack32bit(float data)
{
ushort curDatalen = ;
if (m_OnePackIndex + curDatalen > m_MaxOnePackBuff)
{
MonoBehaviour.print("Pack32bit(float) longer lager than Max buff len");
return;
}
byte[] mBuff = System.BitConverter.GetBytes(data);
Pack(mBuff, curDatalen);
}
public void Pack64bit(double data)
{
ushort curDatalen = ;
if (m_OnePackIndex + curDatalen > m_MaxOnePackBuff)
{
MonoBehaviour.print("Pack64bit(double) longer lager than Max buff len");
return;
}
byte[] mBuff = System.BitConverter.GetBytes(data);
Pack(mBuff, curDatalen);
}
public void Pack64bit(long data)
{
ushort curDatalen = ;
if (m_OnePackIndex + curDatalen > m_MaxOnePackBuff)
{
MonoBehaviour.print("Pack64bit(long) longer lager than Max buff len");
return;
}
byte[] mBuff = System.BitConverter.GetBytes(data);
Pack(mBuff, curDatalen);
} public void PackString(string data, ushort len)
{
ushort curDatalen = len;
if (m_OnePackIndex + curDatalen > m_MaxOnePackBuff)
{
MonoBehaviour.print("PackString() longer lager than Max buff len");
return;
}
byte[] mBuff = System.Text.Encoding.UTF8.GetBytes(data);
Pack(mBuff, curDatalen);
} void Pack(byte[] data, ushort len)
{
System.Buffer.BlockCopy(data, , m_OnePack, m_OnePackIndex, len);
m_OnePackIndex += len;
} public byte[] GetByte()
{
return m_OnePack;
} public int GetByteLen()
{
return m_OnePackIndex;
}
}
}

MsgPack.cs

 using UnityEngine;
/*
* 通信协议
* 消息头前2字节保存当前消息长度
* 后面跟4字节表示消息ID
* 再后面是消息实质内容
*/ namespace LanSocket
{
class MsgUnPack : PackBase
{
ushort m_PackLen;
int m_MsgID;
public MsgUnPack()
{
} void GetHead()
{
m_PackLen = System.BitConverter.ToUInt16(m_OnePack, );
m_MsgID = System.BitConverter.ToUInt16(m_OnePack, );
m_OnePackIndex = ;
} public MsgUnPack(byte[] mBuff, ushort len)
{
UnPack(mBuff, len);
} public MsgUnPack(byte[] mBuff, ushort offset, ushort len)
{
UnPack(mBuff, offset, len);
} public void UnPack(byte[] mBuff, ushort len)
{
System.Buffer.BlockCopy(mBuff, , m_OnePack, , len);
GetHead();
} public void UnPack(byte[] mBuff, ushort offset, ushort len)
{
System.Buffer.BlockCopy(mBuff, offset, m_OnePack, , len);
GetHead();
} public bool Readbool()
{
if (m_OnePackIndex + > m_PackLen)
{
MonoBehaviour.print("Readbool() longer lager than Max buff len");
return false;
}
bool data = System.BitConverter.ToBoolean(m_OnePack, m_OnePackIndex);
++m_OnePackIndex;
return data;
} public short ReadShort()
{
if (m_OnePackIndex + > m_PackLen)
{
MonoBehaviour.print("ReadShort() longer lager than Max buff len");
return ;
}
short data = System.BitConverter.ToInt16(m_OnePack, m_OnePackIndex);
m_OnePackIndex += ;
return data;
} public ushort ReadUShort()
{
if (m_OnePackIndex + > m_PackLen)
{
MonoBehaviour.print("ReadUShortbit() longer lager than Max buff len");
return ;
}
ushort data = System.BitConverter.ToUInt16(m_OnePack, m_OnePackIndex);
m_OnePackIndex += ;
return data;
} public int ReadInt()
{
if (m_OnePackIndex + > m_PackLen)
{
MonoBehaviour.print("ReadInt() longer lager than Max buff len");
return ;
}
int data = System.BitConverter.ToInt32(m_OnePack, m_OnePackIndex);
m_OnePackIndex += ;
return data;
} public uint ReadUInt()
{
if (m_OnePackIndex + > m_PackLen)
{
MonoBehaviour.print("ReadUInt() longer lager than Max buff len");
return ;
}
uint data = System.BitConverter.ToUInt32(m_OnePack, m_OnePackIndex);
m_OnePackIndex += ;
return data;
} public float ReadFloat()
{
if (m_OnePackIndex + > m_PackLen)
{
MonoBehaviour.print("ReadFloat() longer lager than Max buff len");
return 0.0f;
}
float data = System.BitConverter.ToSingle(m_OnePack, m_OnePackIndex);
m_OnePackIndex += ;
return data;
} public double ReadDouble()
{
if (m_OnePackIndex + > m_PackLen)
{
MonoBehaviour.print("ReadDouble() longer lager than Max buff len");
return 0.0f;
}
double data = System.BitConverter.ToDouble(m_OnePack, m_OnePackIndex);
m_OnePackIndex += ;
return data;
} public long ReadLong()
{
if (m_OnePackIndex + > m_PackLen)
{
MonoBehaviour.print("ReadLong() longer lager than Max buff len");
return ;
}
long data = System.BitConverter.ToInt64(m_OnePack, m_OnePackIndex);
m_OnePackIndex += ;
return data;
} public ulong ReadULong()
{
if (m_OnePackIndex + > m_PackLen)
{
MonoBehaviour.print("ReadULong() longer lager than Max buff len");
return ;
}
ulong data = System.BitConverter.ToUInt64(m_OnePack, m_OnePackIndex);
m_OnePackIndex += ;
return data;
} public string ReadString(ushort len)
{
if (m_OnePackIndex + len > m_PackLen)
{
MonoBehaviour.print("ReadString() longer lager than Max buff len");
return "";
}
string data = System.Text.Encoding.UTF8.GetString(m_OnePack, m_OnePackIndex, len);
m_OnePackIndex += len;
return data;
} public int GetMsgID()
{
return m_MsgID;
}
}
}

MsgUnPack.cs

 using UnityEngine;
/*
* 通信协议
* 消息头前2字节保存当前消息长度
* 后面跟4字节表示消息ID
* 再后面是消息实质内容
*/ namespace LanSocket
{
class ClientMsgUnPack : MsgUnPack
{
long m_UserID;
public ClientMsgUnPack()
{
m_UserID = -;
} public ClientMsgUnPack(byte[] mBuff, ushort len, int userID)
{
m_UserID = userID;
UnPack(mBuff, len);
} public ClientMsgUnPack(byte[] mBuff, ushort offset, ushort len, int userID)
{
m_UserID = userID;
UnPack(mBuff, offset, len);
} public long GetUserID()
{
return m_UserID;
} public void SetUserID(long userID)
{
m_UserID = userID;
}
}
}

ClientMsgUnPack.cs

 using UnityEngine;
using System.Collections;
using System.Collections.Generic; delegate void EventDelagate(LanSocket.ClientMsgUnPack msg); class EventNode
{
public int m_EventID;
public LanSocket.ClientMsgUnPack msg;
} class EventDispath
{
public static int g_MaxEventNum = ;
List<EventDelagate>[] m_Event;
Queue<EventNode> m_EventQueue;
public EventDispath()
{
m_Event = new List<EventDelagate>[g_MaxEventNum];
m_EventQueue = new Queue<EventNode>();
} public void RegistEvent(int eventID, EventDelagate func)
{
if(null == m_Event[eventID])
{
m_Event[eventID] = new List<EventDelagate>();
}
m_Event[eventID].Add(func);
} public void AddEvent(EventNode eventNode)
{
m_EventQueue.Enqueue(eventNode);
} public void Proccess()
{
if ( != m_EventQueue.Count)
{
EventNode mCur = m_EventQueue.Dequeue();
if (null == m_Event[mCur.m_EventID])
{
MonoBehaviour.print("event ID: "+ mCur.m_EventID+" is null");
}
else
{
List<EventDelagate> curEventDelagate = m_Event[mCur.m_EventID];
for(int i = ; i < curEventDelagate.Count ; ++i)
{
curEventDelagate[i](mCur.msg);
}
}
}
}
}

EventDispath.cs

unity部分

 using UnityEngine;
using System.Collections; public class ServerMain : MonoBehaviour
{
bool m_Destroy;
EventDispath m_ClientMsg;
void Start ()
{
m_Destroy = false;
//服务器IP地址
LanSocket.Server.Start();
m_ClientMsg = new EventDispath();
m_ClientMsg.RegistEvent(, Action_123); } // Update is called once per frame
void Update ()
{
if(!m_Destroy)
{
LanSocket.ClientMsgUnPack clientMsg = null;
LanSocket.Server.GetMsg(ref clientMsg);
if (null != clientMsg)
{
print("Msg:" + clientMsg.GetMsgID() + " from: " + clientMsg.GetUserID()); EventNode mNode = new EventNode();
mNode.m_EventID = clientMsg.GetMsgID(); ;
mNode.msg = clientMsg;
m_ClientMsg.AddEvent(mNode);
} m_ClientMsg.Proccess();
}
} void OnDestroy()
{
m_Destroy = true;
LanSocket.Server.Destroy();
} void Action_123(LanSocket.ClientMsgUnPack msg)
{
long userID = msg.GetUserID();
ushort accountLen = msg.ReadUShort();
string account = msg.ReadString(accountLen);
ushort passLen = msg.ReadUShort();
string pass = msg.ReadString(passLen); print("Action_123 account: " + account + " pass word: " + pass+" from user: " + userID); LanSocket.MsgPack sendMsg = new LanSocket.MsgPack();
sendMsg.SetHead();
string strAccount = "test account";
sendMsg.Pack16bit((ushort)strAccount.Length);
sendMsg.PackString(strAccount, (ushort)strAccount.Length);
string strPass = "test pass word";
sendMsg.Pack16bit((ushort)strPass.Length);
sendMsg.PackString(strPass, (ushort)strPass.Length);
sendMsg.PackEnd();
LanSocket.Server.SendTo(ref sendMsg, msg.GetUserID());
}
}

ServerMain.cs

 using UnityEngine;
using System.Collections; public class ClientMain : MonoBehaviour { // Use this for initialization
void Start ()
{
LanSocket.Client.Start();
} // Update is called once per frame
void Update ()
{
LanSocket.MsgUnPack msg = null;
LanSocket.Client.GetMsg(ref msg);
if(null != msg)
{
print("here have one msg on client");
} if(Input.GetKeyUp(KeyCode.J))
{
LanSocket.MsgPack sendMsg = new LanSocket.MsgPack();
sendMsg.SetHead();
string strAccount = "test account";
sendMsg.Pack16bit((ushort)strAccount.Length);
sendMsg.PackString(strAccount, (ushort)strAccount.Length);
string strPass = "test pass word";
sendMsg.Pack16bit((ushort)strPass.Length);
sendMsg.PackString(strPass, (ushort)strPass.Length);
sendMsg.PackEnd();
LanSocket.Client.Send(ref sendMsg);
}
}
void OnDestroy()
{
LanSocket.Client.Destroy();
}
}

ClientMain.cs

以上为全部代码,拖到u3d项目中,然后将clientmain或servermain挂在对象上就可以运行了

最新文章

  1. 深入理解javascript原型和闭包(15)——闭包
  2. Java基础-JVM堆与栈
  3. magento使用google analytics
  4. EF 中更新模型的问题,这种错误(因为相同类型的其他实体已具有相同的主键值。)
  5. 暑假集训(2)第五弹 ----- Who&#39;s in the Middle(poj2388)
  6. Java转换
  7. 安卓高级EventBus使用详解
  8. centos7安装nginx1.10.1
  9. oracle dg 报错提示 涉及硬盘错误
  10. flex属性导图
  11. zabbix_agent添加到系统服务启动(八)
  12. 我在大学毕业后学习Linux系统的心得经验
  13. Linux下安装Blender
  14. java spring bean的什么周期
  15. export default与export的区别
  16. CodeForces 1096E: The Top Scorer
  17. python文本 单独处理每个字符的方法汇总
  18. leetcode204
  19. SQL映射文件
  20. 「小程序JAVA实战」小程序我的个人信息-注销功能(42)

热门文章

  1. 算法与数据结构实验题 4.1 伊姐姐数字 game
  2. (beta冲刺5/7)
  3. lintcode-30-插入区间
  4. matlab如何将数组中的NAN值去除
  5. 钉钉 E应用 打开分享外链
  6. [计算机网络] 互联网协议栈(TCP/IP参考模型)各层的主要功能及相应协议
  7. 【Python】python基础_代码编写注意事项
  8. BZOJ 1452 Count(二维树状数组)
  9. 【bzoj4721】[Noip2016]蚯蚓 乱搞
  10. hdu 1848(Fibonacci again and again)(SG博弈)