// 关闭连接 public void OnClosed(object sender, EventArgs e) { try { mClient.Client.Shutdown(SocketShutdown.Both); mClient.GetStream().Close(); mClient.Close(); mClient = null; } catch (Exception exc) { DebugEx.Log(exc.ToString()); } EnableConnect = false; mConnectState = EConnectState.None; mRecvResult = null; mClient = null; mRecvPos = 0; mReceiveCount = 0; mConnectCount = 0; mMessageQueue.Clear(); if (OnConnectClosed != null) { OnConnectClosed(); } }
public void OnConnectError(object sender, ErrorEventArgs e) { mConnectState = EConnectState.None; DebugEx.Log("connect error, ready to close"); try { mClient.Client.Shutdown(SocketShutdown.Both); mClient.GetStream().Close(); mClient.Close(); mClient = null; } catch (Exception exc) { DebugEx.Log(exc.ToString()); } mRecvResult = null; mClient = null; mRecvPos = 0; mReceiveCount = 0; mConnectCount = 0; if (OnConnectServerFailed != null) { OnConnectServerFailed(); } }
public void Disconnect() { ConnectState = EConnectState.None; hostID = HostID_None; lock (csSend) { queSend.Clear(); } try { if (socket == null) { Debug.Log("NetClient.Disconnect() : socket == null"); return; } Debug.Log("NetClient.Disconnect()"); socket.Close(); } catch (Exception ex) { Debug.Log("NetClient.Disconnect() exception : " + ex.ToString()); socket.Close(); } }
private void FinCountdown() { Log.Info("[Info] Connection Closed"); _eConnectState = EConnectState.CLOSED; _socket.Disconnect(false); _socket.Close(); _socket.Dispose(); }
/* * Socket.BeginConnect() 에 바인딩 되어 접속 완료시 호출 * P.S : host thread 에서 호출됨 */ private void OnCallbackConnect(IAsyncResult _iar) { try { Socket socketTemp = (Socket)_iar.AsyncState; if (socketTemp.Connected == false) { if (ConnectState == EConnectState.None) { ErrorTypeJoinServerComplete = ErrorType.ErrorType_TCPConnectFailure; } Debug.Log("OnCallbackConnect() : 접속 실패.!"); return; } socketTemp.EndConnect(_iar); // 메세지 리시브 대기 buffRecvSize = 0; socket.BeginReceive(bufferRecv, buffRecvSize, bufferRecv.Length, SocketFlags.None, asyncCallbackRecv, socket); ConnectState = EConnectState.ConnectVerify; Debug.Log("OnCallbackConnect().!"); } catch (Exception ex) { Debug.Log("OnCallbackConnect() exception : " + ex.ToString()); switch (ConnectState) { case EConnectState.ConnectBegin: { ErrorTypeJoinServerComplete = ErrorType.ErrorType_TCPConnectFailure; ConnectState = EConnectState.None; } break; case EConnectState.ReconnectBegin: { ConnectState = EConnectState.ReconnectFail; } break; } if (socket != null) { socket.Close(); } } }
void SendFIN() { Log.Info("[Info] Send FIN"); Message msg = new Message(); msg.seq = GetCliSeq(); msg.ack = GetSvrSeq(); msg.syn = 0; msg.fin = 1; msg.rsd = 0; msg.ctrl = (byte)ESAFlag.Ctrl; UInt16 len = msg.GetLength(); msg.len = len; _ringSendMsgAckBuffer[msg.seq] = msg; _sender.Send(msg); _eConnectState = EConnectState.FIN_WAIT_1; // _finishTick = Time.realtimeSinceStartup; }
private void SendSYN() { Log.Info("[Info] Send SYN"); Message msg = new Message(); msg.seq = GetCliSeq(); msg.ack = GetSvrSeq(); msg.syn = 1; msg.fin = 0; msg.rsd = 1; msg.ctrl = (byte)ESAFlag.Ctrl; UInt16 len = msg.GetLength(); msg.len = len; _ringSendMsgAckBuffer[msg.seq] = msg; _sender.SendImmediate(msg); _eConnectState = EConnectState.SYN_SENT; Log.InfoFormat("[Info] SendSYN seq = {0} ack = {1}", msg.seq, msg.ack); }
public void Connect(string ip, int port) { m_strServerIP = ip; m_nServerPort = port; object privateLockObject; Monitor.Enter(privateLockObject = m_PrivateLockObject); try { m_ConnectState = EConnectState.PostConnecting; //GameDll.CGameProcedure.s_EventManager.OnNetStateChanged.SafeInvoke((int)NetworkProtol.Tcp, (int)m_ConnectState); m_CurNetwork = Application.internetReachability; m_uNextCheckTime = (uint)UnityEngine.Time.realtimeSinceStartup + 1000u; } finally { Monitor.Exit(privateLockObject); } Debug.Log(string.Concat(new object[] { "Connect:", ip, ":", port, " internettype:", m_CurNetwork })); }
private void SetState(EConnectState pState) { if (lastState == pState) { return; } //set delay so that state is not changed too quickly float delay = lastState == EConnectState.None ? 0 : lastChangeStateTime - Time.time + 1; delay = Mathf.Max(0, delay); lastState = pState; //Debug.Log($"Set state {pState} in {delay} | {Time.time}"); DoInTime(() => UpdateUI(pState), delay); lastChangeStateTime = Time.time + delay; void UpdateUI(EConnectState pNewState) { switch (pNewState) { case EConnectState.Offline: background.color = Color.red; status.text = "Offline"; break; case EConnectState.Connecting: background.color = Color.magenta; status.text = "Connecting..."; break; case EConnectState.Online: background.color = Color.green; status.text = "Online"; break; } } }
// 异步连接远程主机 public void Connect() { if (!EnableConnect) { return; } if (mCanConnectTime > Time.time) { return; } if (mClient != null) { throw new Exception("the socket is connecting, cannot connect again"); } DebugEx.Log("satrt connect ip : " + mIP + " port : " + mPort); IPAddress ipAddress = IPAddress.Parse(mIP); try { mClient = new TcpClient(); mConnectResult = mClient.BeginConnect(mIP, mPort, null, null); mConnectCount = 0; mConnectOverTime = Time.time + mMaxConnectDuration; mConnectState = EConnectState.Connecting; } catch (System.Exception exception) { DebugEx.LogError("connect exception : " + exception.ToString()); mConnectResult = null; OnConnectError(mClient, null); throw; } }
private void ConnectServer() { object privateLockObject; Monitor.Enter(privateLockObject = m_PrivateLockObject); try { m_ConnectState = EConnectState.Connecting; //GameDll.CGameProcedure.s_EventManager.OnNetStateChanged.SafeInvoke((int)NetworkProtol.Tcp, (int)m_ConnectState); } finally { Monitor.Exit(privateLockObject); } if (m_Socket != null) { try { if (m_Socket.Connected) { m_Socket.Shutdown(SocketShutdown.Both); m_Socket.Disconnect(false); } m_Socket.Close(); } catch (Exception exp) { Debug.LogError(exp.Message + exp.StackTrace); } m_Socket = null; } if (m_strServerIP != null && m_nServerPort != 0) { if (m_Socket == null) { m_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); } m_Socket.Connect(m_strServerIP, m_nServerPort); m_Socket.Blocking = false; } Monitor.Enter(privateLockObject = m_PrivateLockObject); try { m_RecvQueue.Clear(); m_SendQueue.Clear(); if (m_ConnectState != EConnectState.PostConnecting) { if (m_Socket != null && m_Socket.Connected) { m_ConnectState = EConnectState.Connected; m_bNetStateChanged = true; //GameDll.CGameProcedure.s_EventManager.OnNetStateChanged.SafeInvoke((int)NetworkProtol.Tcp, (int)m_ConnectState); Debug.Log("Connect Success"); } else { m_ConnectState = EConnectState.Disconnected; m_bNetStateChanged = true; //GameDll.CGameProcedure.s_EventManager.OnNetStateChanged.SafeInvoke((int)NetworkProtol.Tcp, (int)m_ConnectState); } } } finally { Monitor.Exit(privateLockObject); } }
private void WfNetworkThread() { HeaderBytes headbytes = PooledClassManager <HeaderBytes> .CreateClass(); DataBytes databytes = null; int recvedNum = 0; WfPacket sendPacket = null; int sendedNum = 0; while (m_Thread.IsAlive) { try { Thread.Sleep(10); if (m_ConnectState == EConnectState.PostConnecting) { databytes = null; recvedNum = 0; if (sendPacket != null) { sendPacket.DestroyClass(); sendPacket = null; } sendedNum = 0; ConnectServer(); } if (m_ConnectState == EConnectState.Connected) { string errorText = null; bool bWaiting = false; do { errorText = RecvAll(ref headbytes, ref databytes, ref recvedNum, ref bWaiting); }while (errorText == null && !bWaiting); if (errorText == null) { object privateLockObject; Monitor.Enter(privateLockObject = m_PrivateLockObject); try { while (m_SendQueue.Count > 0 || sendPacket != null) { if (sendPacket != null) { errorText = SendAll(sendPacket, ref sendedNum); if (sendedNum == sendPacket.GetOffset()) { sendPacket.DestroyClass(); sendPacket = null; } } if (errorText != null || sendPacket != null || m_SendQueue.Count <= 0) { break; } sendedNum = 0; sendPacket = m_SendQueue.Dequeue(); sendPacket.SetHeadLength(); } } finally { Monitor.Exit(privateLockObject); } } if (errorText != null) { Debug.LogError(errorText); object privateLockObject; Monitor.Enter(privateLockObject = m_PrivateLockObject); try { if (m_ConnectState != EConnectState.PostConnecting) { m_ConnectState = EConnectState.Disconnected; m_bNetStateChanged = true; //GameDll.CGameProcedure.s_EventManager.OnNetStateChanged.SafeInvoke((int)NetworkProtol.Tcp, (int)m_ConnectState); } } finally { Monitor.Exit(privateLockObject); } } } } catch (Exception ex) { Debug.LogError(ex.Message + ex.StackTrace); object privateLockObject; Monitor.Enter(privateLockObject = m_PrivateLockObject); try { if (m_ConnectState != EConnectState.PostConnecting) { m_ConnectState = EConnectState.Disconnected; m_bNetStateChanged = true; //GameDll.CGameProcedure.s_EventManager.OnNetStateChanged.SafeInvoke((int)NetworkProtol.Tcp, (int)m_ConnectState); } } finally { Monitor.Exit(privateLockObject); } } } m_Thread.Abort(); m_Thread.Join(); }
/////////////////////////////////////////////////////////////////////////////////////// // function private private void BeginConnect() { try { if (socket != null) { if (socket.Connected) { Debug.Log("BeginConnect() Already Connected.?"); //socket.Shutdown(SocketShutdown.Both); } socket.Close(); } string convertedHost = startParam.hostname; AddressFamily convertedFamily = AddressFamily.InterNetwork; #if !UNITY_STANDALONE CIPv6Supporter ipv6Supporter = new CIPv6Supporter(); ipv6Supporter.ConvertHostInfo(startParam.hostname, out convertedHost, out convertedFamily); #endif socket = new Socket(convertedFamily, SocketType.Stream, ProtocolType.Tcp); socket.NoDelay = true; #if UNITY_STANDALONE const int IOC_VENDOR = 0x18000000; const int IOC_IN = -2147483648; //0x80000000; const int SIO_TCP_SET_ACK_FREQUENCY = IOC_IN | IOC_VENDOR | 23; byte[] outvalue = BitConverter.GetBytes(0); socket.IOControl(SIO_TCP_SET_ACK_FREQUENCY, BitConverter.GetBytes((int)1), outvalue); #endif socket.BeginConnect(convertedHost, startParam.port, asyncCallbackConnect, socket); ConnectState = EConnectState.ConnectBegin; Debug.Log("BeginConnect().!"); } catch (Exception ex) { Debug.Log("BeginConnect() Exception " + ex.ToString()); switch (ConnectState) { case EConnectState.None: { // 재접속이 아닐 경우만 함수를 통해 클라에 알리자 ErrorTypeJoinServerComplete = ErrorType.ErrorType_TCPConnectFailure; } break; case EConnectState.Reconnecting: { ConnectState = EConnectState.ReconnectFail; } break; } try { if (socket != null) { socket.Close(); } } catch (Exception) { Debug.Log("BeginConnect() socket shutdown Exception " + ex.ToString()); } return; } }
private string RecvAll(ref HeaderBytes msgHeader, ref DataBytes msgData, ref int nRecved, ref bool bWaiting) { string result; if (msgData == null) { SocketError socketError; int recveNum = m_Socket.Receive(msgHeader.Bytes, nRecved, msgHeader.Bytes.Length - nRecved, SocketFlags.None, out socketError); if (recveNum < 0) { result = "消息头小于0"; return(result); } if (socketError != SocketError.Success && socketError != SocketError.WouldBlock) { result = "网络错误:" + socketError.ToString(); m_ConnectState = EConnectState.PostConnecting; m_bNetStateChanged = true; //GameDll.CGameProcedure.s_EventManager.OnNetStateChanged.SafeInvoke((int)NetworkProtol.Tcp, (int)m_ConnectState); return(result); } if (recveNum == 0) { bWaiting = true; result = null; return(result); } nRecved += recveNum; if (nRecved == msgHeader.Bytes.Length) { ushort msgType = 0; ushort msgLength = 0; if (!WfPacket.ParseHeader(msgHeader.Bytes, ref msgType, ref msgLength)) { result = string.Concat(new object[] { "error ParseHeader type:", msgType, "len:", msgLength }); return(result); } if (msgLength < msgHeader.Bytes.Length) { result = string.Concat(new object[] { "error ParseHeader < msglen:", msgLength, "headerLength:", msgHeader.Bytes.Length }); return(result); } if (msgLength == msgHeader.Bytes.Length) { //这里虽然只有一个是一个很简单的只带有消息头的消息,例如心跳,但是我依然用了完整消息大小 msgData = PooledClassManager <DataBytes> .CreateClass(); msgData.SetBytes(msgLength + 1); Array.Copy(msgHeader.Bytes, 0, msgData.GetBytes(), 0, msgHeader.Bytes.Length); WfPacket item = PooledClassManager <WfPacket> .CreateClass(); item.InitRead(msgData); msgData = null; nRecved = 0; object privateLockObject; Monitor.Enter(privateLockObject = m_PrivateLockObject); try { m_RecvQueue.Enqueue(item); } finally { Monitor.Exit(privateLockObject); } } else { msgData = PooledClassManager <DataBytes> .CreateClass(); msgData.SetBytes(msgLength); Array.Copy(msgHeader.Bytes, 0, msgData.GetBytes(), 0, msgHeader.Bytes.Length); nRecved = msgHeader.Bytes.Length; } } } if (msgData != null) { SocketError socketError; int recveNum = m_Socket.Receive(msgData.GetBytes(), nRecved, msgData.GetLength() - nRecved, SocketFlags.None, out socketError); //Debug.Log("底层函数接收数据:" + socketError.ToString()); if (recveNum < 0) { result = "ReceiveData < 0"; return(result); } if (socketError != SocketError.Success && socketError != SocketError.WouldBlock) { result = "ReceiveData Failed"; return(result); } if (recveNum == 0) { bWaiting = true; result = null; return(result); } nRecved += recveNum; if (nRecved > msgData.GetLength()) { result = "ReceiveData IO error"; return(result); } if (nRecved == msgData.GetLength()) { WfPacket item = PooledClassManager <WfPacket> .CreateClass(); item.InitRead(msgData); msgData = null; nRecved = 0; object privateLockObject; Monitor.Enter(privateLockObject = m_PrivateLockObject); try { m_RecvQueue.Enqueue(item); } finally { Monitor.Exit(privateLockObject); } } else { bWaiting = true; } } result = null; return(result); }
private void BeginSend() { try { if (IsConnected == false) { Debug.Log("BeginSend() : IsConnected() == false"); return; } if (ConnectState != EConnectState.Connected) { // 서버와의 기본 통신까지 끝난 상태여야 패킷을 보낼수 있다. Debug.Log("BeginSend() : ConnectState != ReconnectState.Connected"); return; } Message msg = null; lock ( csSend ) { if (queSend.Count == 0) { return; } msg = queSend.Peek(); } switch (msg.RmiContextValue) { case (byte)RmiContext.ReliableCompress: { ZipHelper.CompressToMessage(ref msg); } break; case (byte)RmiContext.FastEncryp: { Crypto.XOREncrypt(msg.buffer, BasicType.HEADSIZE, msg.Length); } break; case (byte)RmiContext.FastEncrypCompress: { Crypto.XOREncrypt(msg.buffer, BasicType.HEADSIZE, msg.Length); ZipHelper.CompressToMessage(ref msg); } break; } ++SequenceNumSend; msg.SequenceNum = SequenceNumSend; socket.BeginSend(msg.buffer, 0, msg.Length, SocketFlags.None, asyncCallbackSend, socket); } catch (Exception ex) { Debug.Log("BeginSend() exception : " + ex.ToString()); try { if (socket != null) { socket.Close(); } } catch (Exception) { Debug.Log("BeginSend() socket shutdown Exception " + ex.ToString()); } ConnectState = EConnectState.None; } }
public NetworkConnection(INetworkClient networkclient) { _rttTime = 3.0f; _networkclient = networkclient; _eConnectState = EConnectState.Null; }
void ProcessRecvBuffer(Message message) { Log.InfoFormat("[ProcessRecvBuffer] receive message seq = {0} ack = {1} ctrl = {2}", message.seq, message.ack, message.ctrl); if (message.ctrl == (byte)ESAFlag.Ctrl)// ctrl message { Log.InfoFormat("[Info] ProcessRecvBuffer Receive Ctrl Message"); // receive syn & ack message if (message.syn == 1) { if (_eConnectState == EConnectState.SYN_SENT) { _base = (byte)(message.ack + 1); _svrSeq = message.seq; OnReceiveAck(); SendCtrlAck(); _eConnectState = EConnectState.ESTABLISHED; Log.InfoFormat("ProcessRecvBuffer _eConnectState from {0} to {1}", EConnectState.SYN_SENT, _eConnectState); } else { Log.InfoFormat("[Info] Receive syn with _eConnectState = {0}", _eConnectState); } } else if (message.fin == 1) { if (_eConnectState == EConnectState.FIN_WAIT_2) { SendCtrlAck(); _eConnectState = EConnectState.TIME_WAIT; Log.InfoFormat("[Info] Receive Fin, Send Ack, _eConnectState from {0} to {1}", EConnectState.FIN_WAIT_2, _eConnectState); _finCountdownId = CountdownTimer.Instance.StartTimer(3, FinCountdown); } else { Log.InfoFormat("[Info] Receive Fin while _eConnectState = {0}", _eConnectState); } } else if (_eConnectState == EConnectState.FIN_WAIT_1)// receive ack message for fin { _base = (byte)(message.ack + 1); OnReceiveAck(); _eConnectState = EConnectState.FIN_WAIT_2; Log.InfoFormat("[Info] Receive Ack Send Nothing, _eConnectState = {0}", _eConnectState); } } else if (message.ctrl == (byte)ESAFlag.Seq) // seq { Log.InfoFormat("[Info] ProcessRecvBuffer Receive seq message"); if (message.seq != GetSvrSeq()) { // ignore receiver 's message Log.InfoFormat("[Info] Receive message.seq = {0} != _svrSeq {1}, discard", message.seq, _svrSeq); ResendAck(); return; } // receive message correctly // handle message // set server seq _svrSeq = message.seq; Log.InfoFormat("[Info] ProcessRecvBuffer message.seq = {0}", message.seq); SendAck(); _networkclient.PostMessage(message); } else if (message.ctrl == (byte)ESAFlag.Ack) //ack { var ack = message.ack; _base = (byte)(ack); Log.InfoFormat("[Info] ProcessRecvBuffer Receive ack message ack = {0}", ack); OnReceiveAck(); } }
/* * Socket.BeginReceive() 바인딩 되어 Packet 을 받게 되면 호출 * P.S : host thread 에서 호출됨 */ private void OnCallbackRecv(IAsyncResult iar) { try { Socket socketTemp = (Socket)iar.AsyncState; if (socketTemp.Connected == false) { Debug.Log("NetClient.OnCallbackRecv() : socketTemp.connected == false"); //if (socket != null) // socket.Close(); return; } int iReadSize = socketTemp.EndReceive(iar); if (iReadSize > 0) { buffRecvSize += iReadSize; /* * 패킷이 나누어져서 오거나 * 2개 이상의 패킷이 하나로 올수 있어서 체크한다(네이글 알골리즘) */ while (buffRecvSize >= sizeof(int)) { Int32 packetLength = 0; packetLength = BitConverter.ToInt32(bufferRecv, 0); if (buffRecvSize >= packetLength) { Message msgRecv = new Message(); Buffer.BlockCopy(bufferRecv, 0, msgRecv.buffer, 0, packetLength); buffRecvSize -= packetLength; if (buffRecvSize >= sizeof(int)) { // 전달할 부분을 빼고 데이터가 남았다면 앞부분으로 당김 Buffer.BlockCopy(bufferRecv, packetLength, bufferRecv, 0, buffRecvSize); } switch (msgRecv.RmiContextValue) { case (byte)RmiContext.ReliableCompress: { ZipHelper.UncompressToMessage(ref msgRecv); } break; case (byte)RmiContext.FastEncryp: { Crypto.XOREncrypt(msgRecv.buffer, BasicType.HEADSIZE, packetLength); } break; case (byte)RmiContext.FastEncrypCompress: { ZipHelper.UncompressToMessage(ref msgRecv); Crypto.XOREncrypt(msgRecv.buffer, BasicType.HEADSIZE, msgRecv.Length); } break; } // HeartBit 회신 if (msgRecv.ID < 0) { OnReceiveServerMessage(msgRecv); continue; } lock ( csRecv ) { // 클라 쓰레드로 전달 queRecv.Enqueue(msgRecv); } } else { // 온전한 패킷을 구성하기에 충분한 데이터가 없음. loop를 빠져나간다. break; } } } else if (iReadSize == 0) { Debug.Log("OnCallbackRecv() ReadSize == 0 : Socket Close"); // LeaveServer 가 FrameMove 에서 호출되면 Socket 종료처리 한다. ErrorTypeLeaveServer = ErrorType.ErrorType_DisconnectFromRemote; ConnectState = EConnectState.None; if (socket != null) { socket.Close(); } return; } // 메세지 리시브 대기 if (IsConnected) { socket.BeginReceive(bufferRecv, buffRecvSize, bufferRecv.Length - buffRecvSize, SocketFlags.None, asyncCallbackRecv, socket); } } catch (Exception ex) { Debug.Log("OnCallbackRecv exception : " + ex.ToString()); try { if (socket != null) { socket.Close(); } } catch (Exception exSub) { Debug.Log("OnCallbackRecv socket shutdown exception : " + exSub.ToString()); } } }
private void OnReceiveServerMessage(Message msg) { switch (msg.ID) { case BasicType.PACKETID_HEART_BIT: { MessageMarshal.Read(msg, out _PingMS); RmiSend(RmiContext.Reliable, BasicType.PACKETID_HEART_BIT, msg); } break; case BasicType.PACKETID_SC_HOSTID_INFO: { if (hostID == HostID_None) { // 신규접속 성공 보냄 Int64 tempHost = HostID_None; MessageMarshal.Read(msg, out tempHost); hostID = tempHost; UInt32 xorKey0, xorKey1, xorKey2; MessageMarshal.Read(msg, out xorKey0); MessageMarshal.Read(msg, out xorKey1); MessageMarshal.Read(msg, out xorKey2); Crypto.XOR_KEY.Clear(); Crypto.XOR_KEY.Add(xorKey0); Crypto.XOR_KEY.Add(xorKey1); Crypto.XOR_KEY.Add(xorKey2); Debug.Log(string.Format("OnReceiveServerMessage(HostInfo) Read( hostID({0}) )", hostID)); Message msgSend = new Message(); msgSend.ID = BasicType.PACKETID_CS_HOSTID_RECV; MessageMarshal.Write(msgSend, hostID); ++SequenceNumSend; msgSend.SequenceNum = SequenceNumSend; msgSend.WriteEnd(); //RmiSend( RmiContext.Reliable, BasicType.PACKETID_CS_HOSTID_RECV, msgSend ); socket.BeginSend(msgSend.buffer, 0, msgSend.Length, SocketFlags.None, asyncCallbackSend, socket); } else { // 재접속 처리 요청 Message msgSend = new Message(); msgSend.ID = BasicType.PACKETID_CS_HOSTID_RECONNECT; ++SequenceNumSend; msgSend.SequenceNum = SequenceNumSend; MessageMarshal.Write(msgSend, hostID); msgSend.WriteEnd(); Int64 remoteID; MessageMarshal.Read(msg, out remoteID); Debug.Log(string.Format("OnReceiveServerMessage(HostInfoRecon) hostID({0}), Read( hostID({1}) )", hostID, remoteID)); try { if (socket.Connected) { // 재접속 중이라 쌓여있는 패킷이 있을수 있어 다이렉트로 회신한다. socket.BeginSend(msgSend.buffer, 0, msgSend.Length, SocketFlags.None, asyncCallbackSend, socket); } } catch { try { if (socket != null) { socket.Close(); } } catch (Exception ex) { Debug.Log("OnReceiveServerMessage() socket shutdown Exception " + ex.ToString()); } } } } break; case BasicType.PACKETID_SC_CONNECT_SUCCESS: { Debug.Log("OnReceiveServerMessage() : PACKETID_SC_CONNECT_SUCCESS"); ConnectState = EConnectState.Connected; ErrorTypeJoinServerComplete = ErrorType.ErrorType_Ok; BeginSend(); } break; case BasicType.PACKETID_SC_RECONNECT_SUCCESS: { ConnectState = EConnectState.Connected; Debug.Log(string.Format("OnReceiveServerMessage() " + BasicType.PACKETID_SC_RECONNECT_SUCCESS.ToString())); } break; case BasicType.PACKETID_SC_RECONNECT_FAIL: { Debug.Log(string.Format("OnReceiveServerMessage() " + BasicType.PACKETID_SC_RECONNECT_FAIL.ToString())); /* * 재접속 실패일 경우 클라에서는 접속중으로 인식하기 때문에 접속 종료를 알리자 * LeaveServer 가 FrameMove 에서 호출되면 Socket 종료처리 한다. */ ErrorTypeLeaveServer = ErrorType.ErrorType_ReconnectFail; } break; } }
/* * 클라이언트 Tick 에서 호출해주어야 한다. * Recv 된 패킷이 queue 되어 있을 경우 1 frame 당 1개의 packet 을 OnPacketReceive() 을 통해 전달 해준다 */ public void FrameMove() { if (startParam == null || startParam.IsValid == false) { return; } if (ErrorTypeJoinServerComplete != ErrorType.ErrorType_None) { startParam.OnJoinServerComplete(ErrorTypeJoinServerComplete); ErrorTypeJoinServerComplete = ErrorType.ErrorType_None; } if (ErrorTypeLeaveServer != ErrorType.ErrorType_None) { startParam.OnLeaveServer(ErrorTypeLeaveServer); ErrorTypeLeaveServer = ErrorType.ErrorType_None; Disconnect(); } try { if (socket != null && socket.Connected == false) { // 재접속.? switch (ConnectState) { case EConnectState.Connected: { tmReconnectStart = DateTime.Now; ConnectState = EConnectState.Reconnecting; BeginConnect(); } break; case EConnectState.ReconnectFail: { var tmValue = DateTime.Now - tmReconnectStart; if (tmValue.TotalSeconds >= 60) { // 재접속 연결 시간이 지나면 종료하자(1분) ErrorTypeLeaveServer = ErrorType.ErrorType_ReconnectFail; ConnectState = EConnectState.ReconnectClose; break; } ConnectState = EConnectState.Reconnecting; BeginConnect(); } break; } return; } } catch (Exception ex) { Debug.Log("FrameMove exception : " + ex.ToString()); } List <Message> vecRecv = new List <Message>(); lock ( csRecv ) { while (queRecv.Count > 0) { vecRecv.Add(queRecv.Dequeue()); } } if (vecRecv.Count > 0) { foreach (var bufferRecv in vecRecv) { bool IsStub = false; foreach (var stub in listRmiStub) { if (stub.ProcessReceivedMessage(bufferRecv)) { IsStub = true; break; } } if (IsStub == false && startParam.OnReceiveMessage != null) { startParam.OnReceiveMessage(bufferRecv); IsStub = true; } if (IsStub == false && listRmiStub.Count > 0) { Debug.Log("function that a user did not create has been called. : listRmiStub.Count > 0"); } } } }
public void Update(float deltaTime) { if (mConnectState == EConnectState.Connected) // 已连接状态 { DealWithMsg(); if (mRecvResult != null) { if (mReceiveCount > mMaxReceiveCount && Time.time > mReceiveOverTime) { DebugEx.LogError("recv data over 200, so close network"); Close(); return; } ++mReceiveCount; if (mRecvResult.IsCompleted) { try { Int32 readSize = mClient.GetStream().EndRead(mRecvResult); // 从流中读取的字节数 mRecvPos += readSize; if (readSize == 0) { DebugEx.LogError("can't recv data now, so close network"); Close(); return; } } catch (System.Exception exception) { DebugEx.LogError(exception.ToString()); Close(); return; } OnDataReceived(); if (mClient != null) { try { // 从流中读取数据存放到mRecvBuffer中,从mRecvPos位置开始存放 mRecvResult = mClient.GetStream().BeginRead(mRecvBuffer, mRecvPos, mRecvBuffer.Length - mRecvPos, null, null); mReceiveOverTime = Time.time + mMaxReceiveDuration; mReceiveCount = 0; } catch (System.Exception exception) { DebugEx.LogError(exception.ToString()); Close(); return; } } } } if (mClient != null && mClient.Connected == false) { DebugEx.LogError("client is close by system, so close it now"); Close(); return; } } else if (mConnectState == EConnectState.Connecting) // 正在连接状态 { if (mConnectCount > mMaxConnectCount && Time.time > mConnectOverTime) { DebugEx.LogError("can't connect, so close network"); mConnectResult = null; OnConnectError(mClient, null); return; } // 记录连接历经的帧数 ++mConnectCount; if (mConnectResult.IsCompleted) // 连接完成 { mConnectState = EConnectState.Connected; mConnectResult = null; if (mClient.Connected) { try { mClient.NoDelay = true; mClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, 2000); mClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 2000); mClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true); mRecvResult = mClient.GetStream().BeginRead(mRecvBuffer, 0, mRecvBuffer.Length, null, null); mReceiveOverTime = Time.time + mMaxReceiveDuration; mReceiveCount = 0; OnConnected(mClient, null); } catch (Exception exception) { DebugEx.LogError(exception.ToString()); Close(); return; } } else { OnConnectError(mClient, null); } } } else { Connect(); } }