unity C#实现简单socket通讯框架
Posted 左右...
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了unity C#实现简单socket通讯框架相关的知识,希望对你有一定的参考价值。
工程源码地址:https://download.csdn.net/download/u014261855/13099895
话不多少,直接上代码:
1.封装socket内核,客户端服务端公用
/// <summary>
/// socket内核
/// </summary>
public class SFxSocket
private Socket _Socket;
private string _IP;
private int _Port;
private Thread _ReveiveThread;
private bool _ReveiveContral = false;
private int _BuffLen = 64;
#region Instance
public SFxSocket(string ip, int port)
_IP = ip;
_Port = port;
_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
public SFxSocket(Socket s)
_Socket = s;
public void Connect()
IPAddress ip = IPAddress.Parse(_IP);
EndPoint point = new IPEndPoint(ip, _Port);
_Socket.BeginConnect(point, OnConnect, null);
public void OpenReceive()
Log("OpenReceive");
_ReveiveContral = true;
_ReveiveThread = new Thread(ReceiveThread);
_ReveiveThread.IsBackground = true;
_ReveiveThread.Start();
public void Send(byte[] buf)
try
_Socket.BeginSend(buf, 0, buf.Length, SocketFlags.None, OnSend, _Socket);
catch (Exception e)
Log("Send:" + e.Message);
public void Close()
_ReveiveContral = false;
//_ReveiveThread.Abort();
if (_Socket != null)
_Socket.Shutdown(SocketShutdown.Both);
_Socket.Close();
_Socket = null;
#endregion
private void ReceiveThread()
while (_ReveiveContral)
if (_Socket == null) continue;
try
byte[] buf = new byte[_BuffLen];
int size = _Socket.Receive(buf);
OnReceive(buf, size);
catch (Exception e)
Log("ReveiveThread:" + e.Message);
break;
Thread.Sleep(100);
private void OnConnect(IAsyncResult r)
Log("OnConnect");
OpenReceive();
private void OnReceive(byte[] buf, int size)
byte[] value = Polling(buf, size);
if (!CheckZero(value)) return;
SFxMessagerCenter<int,byte[]>.Broadcast("OnReceiveBuf", this.GetHashCode(), buf);
private void OnSend(IAsyncResult r)
Log("OnSend");
#region Util
private bool CheckZero(byte[] buf)
for (int i = 0; i < buf.Length; i++)
if (buf[i] != 0) return true;
return false;
private void Log(string log)
SFxMessagerCenter<string>.Broadcast("SFSocketMsg", log);
private byte[] Polling(byte[] buf, int size)
byte[] r = new byte[size];
for (int i = 0; i < size; i++)
r[i] = buf[i];
return r;
#endregion
其中SFxMessagerCenter是我封装的一个简单的消息处理器,集成三个方法Register、UnRegister、Broadcast,详细见工程。
2.封装协议包
/// <summary>
/// 数据包基类
/// </summary>
public class SFxPakage
byte[] _Buffer;
public virtual void Init(byte[] buf)
_Buffer = buf;
public virtual byte[] ToArray()
return _Buffer;
public int ReadInt()
int r = BitConverter.ToInt32(SFxUtil.GetByte(_Buffer,4),0);
_Buffer = SFxUtil.RemoveByte(_Buffer,4);
return r;
public void WriteInt(int parm)
byte [] bytes = BitConverter.GetBytes(parm);
_Buffer = SFxUtil.AddByte(_Buffer,bytes);
public class SFxPakageHead : SFxPakage
public int Version = 4096;
public int ID = 0;
public static int _BufferSize = 8;
public static int _Version = 4096;
public override void Init(byte[] buf)
base.Init(buf);
Version = ReadInt();
ID = ReadInt();
public override byte[] ToArray()
WriteInt(Version);
WriteInt(ID);
return base.ToArray();
SFxPakage目前只实现了ReadInt、WriteInt方法,其他字节解析可以看情况增加。
3.封装服务器
/// <summary>
/// 服务端socket
/// 消息:SFSocketMsg 参数string
/// 消息:OnReceivePag 参数int hash, int id,byte[] buf
/// </summary>
public class SFxServer
Socket _Socket;
int _Port;
List<SFxSocket> _SocketServerList = new List<SFxSocket>();
bool IsActive = false;
public SFxServer(int port)
IsActive = true;
_Port = port;
_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
public void Open()
IPAddress add = IPAddress.Parse("127.0.0.1");
EndPoint point = new IPEndPoint(add, _Port);
_Socket.Bind(point);
_Socket.Listen(10);
AcceptThread();
Console.WriteLine("启动服务");
SFxMessagerCenter<int, byte[]>.Register("OnReceiveBuf", OnReceive);
public void Close()
Console.WriteLine("关闭服务");
IsActive = false;
for (int i = 0; i < _SocketServerList.Count; i++)
_SocketServerList[i].Close();
_SocketServerList.Clear();
_Socket.Close();
_Socket = null;
public void SendToAllClient(int id, SFxPakage pakage)
Console.WriteLine("SendToAllClient id = " + id);
SFxPakageHead head = new SFxPakageHead();
head.ID = id;
byte[] sendbuf = SFxUtil.AddByte(head.ToArray(), pakage.ToArray());
for (int i = 0; i < _SocketServerList.Count; i++)
_SocketServerList[i].Send(sendbuf);
public void SendToAllClient(byte [] pakage)
Console.WriteLine("SendToAllClient len = " + pakage.Length);
for (int i = 0; i < _SocketServerList.Count; i++)
_SocketServerList[i].Send(pakage);
void AcceptThread()
Console.WriteLine("开始接收");
_Socket.BeginAccept(OnAccept, _Socket);
void OnAccept(IAsyncResult r)
if (!IsActive) return;
Socket s = (Socket)r.AsyncState;
Socket ar = s.EndAccept(r);
SFxSocket socketServer = new SFxSocket(ar);
_SocketServerList.Add(socketServer);
socketServer.OpenReceive();
Console.WriteLine("接收到连接 hash = " + socketServer.GetHashCode());
AcceptThread();
void OnReceive(int socketHash, byte[] buf)
if (buf.Length < SFxPakageHead._BufferSize) return;
SFxPakageHead head = new SFxPakageHead();
head.Init(SFxUtil.GetByte(buf, SFxPakageHead._BufferSize));
if (head.Version == SFxPakageHead._Version)
SFxMessagerCenter<int, int, byte[]>.Broadcast("OnReceivePag", socketHash, head.ID, SFxUtil.RemoveByte(buf, SFxPakageHead._BufferSize));
public int GetConnectCount()
return _SocketServerList.Count;
服务器对象使用简单,直接new一个对象,调用Open()方法即可,需要通讯的话就监听OnReceive的方法。
4.封装客户端
/// <summary>
/// 客户端socket
/// 消息:SFSocketMsg 参数string
/// 消息:OnReceivePag 参数int id, byte[] buf
/// </summary>
public class SFxClient
SFxSocket _Socket;
public SFxClient(string ip,int port)
_Socket = new SFxSocket(ip, port);
SFxMessagerCenter<int, byte[]>.Register("OnReceiveBuf", OnReceive);
public void Connect()
if (_Socket != null) _Socket.Connect();
public void Send(int id, SFxPakage pakage)
if (_Socket == null) return;
SFxPakageHead head = new SFxPakageHead();
head.ID = id;
byte[] r = SFxUtil.AddByte(head.ToArray(), pakage.ToArray());
_Socket.Send(r);
public void Close()
if (_Socket != null)
_Socket.Close();
_Socket = null;
void OnReceive(int socketHash, byte[] buf)
if (buf.Length < SFxPakageHead._BufferSize) return;
SFxPakageHead head = new SFxPakageHead();
head.Init(SFxUtil.GetByte(buf, SFxPakageHead._BufferSize));
if (head.Version == SFxPakageHead._Version)
SFxMessagerCenter<int, byte[]>.Broadcast("OnReceivePag", head.ID, SFxUtil.RemoveByte(buf, SFxPakageHead._BufferSize));
直接new对象然后connect即可
5.还封装一个SFxHardware对象,用来直接跟服务器进行byte流通信(这里的服务器是外部的socket服务器,非本项目封装服务器对象)大家自己研究。
以上是关于unity C#实现简单socket通讯框架的主要内容,如果未能解决你的问题,请参考以下文章
[经验] Java 使用 netty 框架, 向 Unity 客户端的 C# 实现通信[2]