/* * 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 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; } }