/// <summary> /// 连接服务器 /// </summary> /// <param name="_currIP"></param> /// <param name="_currPort"></param> internal void Connect(string _currIP, int _currPort) { if (!IsConnceted) { try { //创建套接字 clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //解析IP地址 IPAddress ipAddress = IPAddress.Parse(_currIP); IPEndPoint ipEndpoint = new IPEndPoint(ipAddress, _currPort); //异步连接 IAsyncResult result = clientSocket.BeginConnect(ipEndpoint, new AsyncCallback(_onConnect_Sucess), clientSocket); bool success = result.AsyncWaitHandle.WaitOne(5000, true); if (!success) { //超时 Close(); } } catch (Exception _e) { //失败 Close(); SGNFDebug.ExceptionCaught(_e); } } }
/// <summary> /// 连接成功,建立接受线程 /// </summary> /// <param name="iar"></param> private void _onConnect_Sucess(IAsyncResult iar) { try { Socket client = (Socket)iar.AsyncState; client.EndConnect(iar); receiveThread = new Thread(new ThreadStart(_onReceiveSocket)); receiveThread.IsBackground = true; receiveThread.Start(); _isConnected = true; SGNFDebug.Log("InfoServer connected!"); SGNFDebug.Log("Requesting ScenarioServer list..."); byte[] rawData = SocketUtil.ISSerial(new ISSocketModel() { Command = (int)SocketUtil.InternalCommand.SSINFO, }); Instance.SendMsgBase(rawData); } catch (Exception _e) { Close(); SGNFDebug.ExceptionCaught(_e); } }
/// <summary> /// 发送消息结果回调,可判断当前网络状态 /// </summary> /// <param name="asyncSend"></param> private void _onSendMsg(IAsyncResult asyncSend) { try { Socket client = (Socket)asyncSend.AsyncState; client.EndSend(asyncSend); } catch (Exception e) { SGNFDebug.ExceptionCaught(e); } }
/// <summary> /// 发送消息基本方法 /// </summary> /// <param name="_protocalType"></param> /// <param name="_data"></param> internal void SendMsgBase(byte[] _data) { if (clientSocket == null || !clientSocket.Connected) { SGNFDebug.Log("InfoServer didn't connected at all!"); return; } byte[] data = new byte[4 + _data.Length]; SocketUtil.IntToBytes(_data.Length).CopyTo(data, 0); _data.CopyTo(data, 4); SGNFDebug.HEXLog("send", data, data.Length); clientSocket.BeginSend(data, 0, data.Length, SocketFlags.None, new AsyncCallback(_onSendMsg), clientSocket); }
/// <summary> /// 添加缓存数据 /// </summary> /// <param name="_data"></param> /// <param name="_dataLen"></param> public void AddBuffer(byte[] _data, int _dataLen) { if (_dataLen > _buff.Length - _curBuffPosition)//超过当前缓存 { byte[] _tmpBuff = new byte[_curBuffPosition + _dataLen]; Array.Copy(_buff, 0, _tmpBuff, 0, _curBuffPosition); Array.Copy(_data, 0, _tmpBuff, _curBuffPosition, _dataLen); _buff = _tmpBuff; _tmpBuff = null; } else { Array.Copy(_data, 0, _buff, _curBuffPosition, _dataLen); } _curBuffPosition += _dataLen;//修改当前数据标记 SGNFDebug.HEXLog("current buffer", _buff, _buff.Length); }
/// <summary> /// 断开 /// </summary> internal void Close() { if (!_isConnected) { return; } _isConnected = false; if (receiveThread != null) { receiveThread.Abort(); receiveThread = null; } if (clientSocket != null && clientSocket.Connected) { clientSocket.Close(); clientSocket = null; } SGNFDebug.Log("InfoServer disconnected!"); }
/// <summary> /// 接受网络数据,将接受到的放入消息队列 /// </summary> private void _onReceiveSocket() { while (true) { if (!clientSocket.Connected) { _isConnected = false; break; } try { int receiveLength = clientSocket.Receive(_tmpReceiveBuff); if (receiveLength > 0) { //将收到的数据添加到缓存器中 _databuffer.AddBuffer(_tmpReceiveBuff, receiveLength); SGNFDebug.HEXLog("rcv", _tmpReceiveBuff, receiveLength); //取出一条完整数据 while (_databuffer.GetData(out _socketData)) { ISSocketModel DeData = SocketUtil.ISDeSerial(_socketData); //如果数据属于内部协议 if (Enum.IsDefined(typeof(SocketUtil.InternalCommand), DeData.Command)) { if (DeData.Command == (int)SocketUtil.InternalCommand.NULL) { SGNFDebug.Log("Got NULL from server"); } if (DeData.Command == (int)SocketUtil.InternalCommand.PING) { //Client.RcvPingStr = DeData.Message[0]; } if (DeData.Command == (int)SocketUtil.InternalCommand.SSINFO) { int num = Convert.ToInt32(DeData.Message[0]); if (num > 0) { NetManager.Instance.allSSInfo.Clear(); for (int i = 0; i < num; i++) { NetManager.Instance.allSSInfo.Add(new SocketUtil.SSInfo() { Tag = DeData.Message[i * 3 + 1], IP = DeData.Message[i * 3 + 2], Port = Convert.ToInt32(DeData.Message[i * 3 + 3]), }); } } SGNFDebug.ListLog("Got " + num + " row of SS from server", NetManager.Instance.allSSInfo); } } else { //锁死消息中心消息队列,并添加数据 lock (MessageCenter.Instance.ISMessageDataQueue) { MessageCenter.Instance.ISMessageDataQueue.Enqueue(DeData); } } } } } catch (Exception e) { clientSocket.Disconnect(true); clientSocket.Shutdown(SocketShutdown.Both); clientSocket.Close(); SGNFDebug.ExceptionCaught(e); break; } } }
/// <summary> /// 接受网络数据,将接受到的放入消息队列 /// </summary> private void _onReceiveSocket() { while (true) { if (!clientSocket.Connected) { _isConnected = false; break; } try { int receiveLength = clientSocket.Receive(_tmpReceiveBuff); if (receiveLength > 0) { //将收到的数据添加到缓存器中 _databuffer.AddBuffer(_tmpReceiveBuff, receiveLength); SGNFDebug.HEXLog("rcv", _tmpReceiveBuff, receiveLength); //取出一条完整数据 while (_databuffer.GetData(out _socketData)) { SSSocketModel DeData = SocketUtil.SSDeSerial(_socketData); //如果数据属于内部协议 if (Enum.IsDefined(typeof(SocketUtil.InternalCommand), DeData.Command)) { if (DeData.Command == (int)SocketUtil.InternalCommand.NULL) { SGNFDebug.Log("Got NULL from server"); } if (DeData.Command == (int)SocketUtil.InternalCommand.PING) { //Client.RcvPingStr = DeData.Message[0]; } if (DeData.Command == (int)SocketUtil.InternalCommand.TICK) { if (DeData.Message.Count >= 1) { NetManager.Instance.tick = DeData.Message[0]; SGNFDebug.Log("Got Tick!Which is " + DeData.Message[0]); } else { SGNFDebug.ExceptionCaught(new Exception("Recieved nothing from TICK package!"));; } } } else { lock (SSRecorder.Instance.RecieveDataBuffer) { SSRecorder.Instance.RecieveDataBuffer.Add(DeData.CurrentTick, DeData); } //锁死消息中心消息队列,并添加数据 lock (MessageCenter.Instance.SSMessageDataQueue) { MessageCenter.Instance.SSMessageDataQueue.Enqueue(DeData); } } } } } catch (Exception e) { clientSocket.Disconnect(true); clientSocket.Shutdown(SocketShutdown.Both); clientSocket.Close(); SGNFDebug.ExceptionCaught(e); break; } } }