using System.Net.Sockets; using System; using UnityEngine; using System.Collections.Generic; using LitJson; public class ClientSocket { private static ClientSocket mInstance; public static ClientSocket instance { get { if (mInstance == null) mInstance = new ClientSocket(); return mInstance; } } public bool connected = false; private byte[] mRecvBuff; private Socket mSocket; private AsyncCallback mRecvCb; private Queue mMSgQueue = new Queue(); private Socket Init() { Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // 接收的消息数据包大小限制为0x4000bytes,即16KB mRecvBuff = new byte[0x4000]; mRecvCb = new AsyncCallback(RecvCallBack); return clientSocket; } /// /// 连接服务器 /// /// ip地址 /// 端口 public void Connect(string host, int port) { if (mSocket == null) mSocket = Init(); try { GameLogger.Log("connect: " + host + ":" + port); mSocket.SendTimeout = 3; mSocket.Connect(host, port); connected = true; } catch (Exception e) { GameLogger.LogError(e); } } /// /// 发送消息 /// /// public void SendData(byte[] bytes) { NetworkStream netstream = new NetworkStream(mSocket); netstream.Write(bytes, 0, bytes.Length); } public void SendData(string jsonStr) { SendData(System.Text.Encoding.UTF8.GetBytes(jsonStr)); } /// /// 尝试接收消息(每帧调用) /// public void BeginReceive() { mSocket.BeginReceive(mRecvBuff, 0, mRecvBuff.Length, SocketFlags.None, mRecvCb, this); } /// /// 当收到服务器的消息时会回调这个函数 /// /// private void RecvCallBack(IAsyncResult ar) { var len = mSocket.EndReceive(ar); byte[] msg = new byte[len]; Array.Copy(mRecvBuff, msg, len); var msgStr = System.Text.Encoding.UTF8.GetString(msg); // 将消息塞入队列中 mMSgQueue.Enqueue(msgStr); // 将buffer清零 for (int i = 0; i < mRecvBuff.Length; i++) { mRecvBuff[i] = 0; } } /// /// 从消息队列中取出消息(供外部调用) /// /// public string GetMsgFromQueue() { if (mMSgQueue.Count > 0) return mMSgQueue.Dequeue(); return null; } /// /// 关闭Socket /// public void CloseSocket() { GameLogger.Log("close socket"); try { mSocket.Shutdown(SocketShutdown.Both); mSocket.Close(); } catch (Exception e) { // GameLogger.LogError(e); } finally { mSocket = null; connected = false; } } }