简单的异步socket示例
简单过一下主要使用到的相关API:
public class Socket : IDisposable
{
public Socket(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType);
// 连接指定地址&端口
public void Connect(EndPoint remoteEP);
// 异步接收, 指定callback函数处理到来的函数(自动创建线程去跑callback函数)
public IAsyncResult BeginReceive(byte[] buffer, int offset, int size, SocketFlags socketFlags, AsyncCallback callback, object state);
// 异步发送, 类似BeginReceive
public IAsyncResult BeginSend(byte[] buffer, int offset, int size, SocketFlags socketFlags, AsyncCallback callback, object state);
//....
}
Unity3D新建脚本文件:ClientSocket.cs
using UnityEngine;
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using UnityEngine.Assertions;
using System.Threading;
public class ClientSocketD
{
//每个数据包都有一个2byte表示长度的头部
const int PACKAGE_LEN_BYTE = 2;
Socket m_socket = null;
byte[] m_receiveBuffer = new byte[1 << (PACKAGE_LEN_BYTE * 2) + 2];
int m_receiveBufUsed = 0;
//这里定义数据包的分发函数, 如解密、拆箱成对象、分发对应处理函数
public delegate void Dispatch(byte[] szData);
Dispatch m_dispatch = null;
static private ClientSocketD m_instance;
private ClientSocketD()
{
}
static public ClientSocketD GetInstance()
{
if(m_instance == null)
{
m_instance = new ClientSocketD();
}
return m_instance;
}
public bool IsConnect()
{
return m_socket == null;
}
public void Init(string server, int port, Dispatch handler = null)
{
m_dispatch = handler;
IPHostEntry hostEntry = null;
hostEntry = Dns.GetHostEntry(server);
foreach (IPAddress address in hostEntry.AddressList)
{
IPEndPoint ipe = new IPEndPoint(address, port);
Socket tempSocket =
new Socket(ipe.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
tempSocket.Connect(ipe);
if (tempSocket.Connected)
{
m_socket = tempSocket;
Debug.Log("connect success");
break;
}
else
{
continue;
}
}
return;
}
static int GetPackLen(byte[] szData)
{
return ((int)szData[0] << 4) + szData[1];
}
//打包,在数据包开头用两字节记录包的大小。
static byte[] PackBig2(byte[] data)
{
int iLen = data.Length;
Assert.IsFalse(iLen <= 0 || iLen > (1 << PACKAGE_LEN_BYTE * 8), "C pack too big");
byte[] szPackage = new byte[PACKAGE_LEN_BYTE + iLen];
szPackage[0] = (byte)((iLen & 0xf0) >> 4);
szPackage[1] = (byte)((iLen & 0x0f));
Array.Copy(data, 0, szPackage, PACKAGE_LEN_BYTE, iLen);
return szPackage;
}
//解包
public void UnPackDispatch()
{
if (m_receiveBufUsed > PACKAGE_LEN_BYTE)
{
int len = GetPackLen(m_receiveBuffer);
int start = 0;
while (len + PACKAGE_LEN_BYTE <= m_receiveBufUsed - start)