c# socket select 模型代码(u3d)
其实写过多次网络链接。但是因为换了工作,又没电脑在身边,所以以前的代码都没办法翻出来用。
所以从今天起,一些常用的代码只好放到网上。
公司有一个局域网的游戏。本来想用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挂在对象上就可以运行了
c# socket select 模型代码(u3d)的更多相关文章
- u3d局域网游戏网络(c# socket select 模型)
之前写了一篇. 发完之后第二天实际应用到游戏之后还是发现了一些小毛病. 比如网络模块有重复使用(多对象)的情况.所以将静态类该成了普通类. 比如安卓下会有些异常出现导致游戏逻辑不正常.所以网络相关的函 ...
- u3d局域网游戏网络(c# socket select 模型)——续
原文:http://www.cnblogs.com/saucerman/p/5555793.html 因为项目要加语音.语音数据都非常大.所以顺带就把之前写的网络模块一起测试了. 然后发现了一些bug ...
- socket select模型
由于socket recv()方法是堵塞式的,当多个客户端连接服务器时,其中一个socket的recv调用时,会产生堵塞,使其他连接不能继续. 如果想改变这种一直等下去的焦急状态,可以多线程来实现(不 ...
- socket select()模型
转载:http://www.cnblogs.com/xiangshancuizhu/archive/2012/10/05/2711882.html 由于socket recv()方法是阻塞式的,当有多 ...
- C# Socket select模型
http://www.cnblogs.com/Clingingboy/archive/2011/07/04/2097806.html http://www.cnblogs.com/RascallySn ...
- 多路复用I/O模型select() 模型 代码实现
多路复用I/O: socket编程之select(),poll(),epoll() 代码: client.c #include <stdio.h> #include <sys/ty ...
- windows socket编程select模型使用
int select( int nfds, //忽略 fd_ser* readfds, //指向一个套接字集合,用来检测其可读性 ...
- socket编程的select模型
在掌握了socket相关的一些函数后,套接字编程还是比较简单的,日常工作中碰到很多的问题就是客户端/服务器模型中,如何让服务端在同一时间高效的处理多个客户端的连接,我们的处理办法可能会是在服务端不停的 ...
- socket之 select模型
前段时间一直想学习网络编程的select模型,看了<windows网络编程>的介绍,参考了别人的博客. 这里的资料主要来自http://www.cnblogs.com/RascallySn ...
随机推荐
- 20145214 《Java程序设计》第9周学习总结
20145214 <Java程序设计>第9周学习总结 教材学习内容总结 JDBC简介 JDBC全名Java DataBase Connectivity,是java联机数据库的标准规范.它定 ...
- lintcode-184-最大数
184-最大数 给出一组非负整数,重新排列他们的顺序把他们组成一个最大的整数. 注意事项 最后的结果可能很大,所以我们返回一个字符串来代替这个整数. #### 样例 给出 [1, 20, 23, 4, ...
- grid++json页面数据传入
最近遇到一个问题,就是要用Grid++做页面数据报表打印,但是翻了Grid++文档就是没有直接从页面上传数据的,都是要加载txt文档,填写txt文档的url.自己尝试直接页面上传JSON数据到Grid ...
- 【week2】四人小组项目(WBS、NABCD)
项目选题:东北师范大学论坛 小组名称:nice! 项目组长:李权 组员:于淼 刘芳芳 杨柳 本周任务:要求给出需求概述.功能列表.痛点或亮点.NABCD及WBS模型在此项目中的应用. 作为东北师范大学 ...
- PAT 1058 选择题
https://pintia.cn/problem-sets/994805260223102976/problems/994805270356541440 批改多选题是比较麻烦的事情,本题就请你写个程 ...
- [转]Windows 7 蓝屏后获取 MEMORY.DMP 文件及注意事项
转自:http://hi.baidu.com/guicomeon/item/d6753a177fc76f0f8fbde46a 系统默认会在 C:\Windows 目录下创建 MEMORY.DMP 文件 ...
- 安全的API接口解决方案
在各种手机APP泛滥的现在,背后都有同样泛滥的API接口在支撑,其中鱼龙混杂,直接裸奔的WEB API大量存在,安全性令人堪优 在以前WEB API概念没有很普及的时候,都采用自已定义的接口和结构,对 ...
- WITH REPLACE 含义
RESTORE DATABASE db_CSharp from disk='backup.bak' WITH REPLACE WITH REPLACE后面是限定条件,with replace意思是替换 ...
- linux下清空文件全部内容,如log日志
在实际操作中经常需要清空log文件, 比如a.log, 有的人说, 直接删除不就行了, 但是, 直接删除后, 没法使用tail -f a.log了. 有的人说, 先rm再touch一个新文件不就可 ...
- Redis 学习之数据类型
该文使用centos6.5 64位 redis-3.2.8 [root@localhost bin]# netstat -tunpl |grep 6379 查看redis 是否启动成功 一.Stri ...