Пример #1
0
 public NetMessageStream(NetMessageBody msgBody)
 {
     m_msg = new NetMessage(new NetMessageHeader(), msgBody);
 }
Пример #2
0
 public void SetMessage(NetMessageBody msgBody)
 {
     m_msg = new NetMessage(new NetMessageHeader(), msgBody);
 }
Пример #3
0
        protected void ReceiverThreadJob()
        {
            try
            {
                while (m_receiverRun)
                {
                    // 데이터가 들어올때까지 대기하다가 종료플래그가 서면 종료
                    if (WaitDataAndDoJob(m_socket) == false)
                    {
                        break;
                    }


                    int readResult = 0;

                    // 헤더 읽고 생성
                    byte[] headerBytes = new byte[NetMessageHeader.ByteSize];

                    int recvSize = 0;

                    while (recvSize < headerBytes.Length)
                    {
                        try
                        {
                            readResult = m_socket.Receive(headerBytes, recvSize,
                                                          headerBytes.Length - recvSize, SocketFlags.None);
                        }
                        catch
                        { }

                        // 읽기 실패
                        if (readResult <= 0)
                        {
                            break;
                        }
                        else
                        {
                            recvSize += readResult;
                        }
                    }

                    NetMessageHeader header = new NetMessageHeader(headerBytes);


                    // 헤더가 유효하지 않으면
                    if (header.IsValid == false)
                    {
                        // 남은 데이터를 모두 버림.
                        while (m_socket.Available > 0)
                        {
                            byte[] tempBuffer = new byte[m_socket.Available];
                            m_socket.Receive(tempBuffer, 0, tempBuffer.Length, SocketFlags.None);
                        }
                    }
                    else
                    {
                        // 읽어야할 바디 크기가 있으면
                        if (header.BodySize > 0)
                        {
                            // 데이터가 들어올때까지 대기하다가 종료플래그가 서면 종료
                            if (WaitDataAndDoJob(m_socket) == false)
                            {
                                break;
                            }


                            readResult = 0;

                            // 바디 읽고 생성
                            byte[] bodyBytes = new byte[header.BodySize];

                            int recvBodySize = 0;

                            while (recvBodySize < bodyBytes.Length)
                            {
                                try
                                {
                                    readResult = m_socket.Receive(bodyBytes, recvBodySize,
                                                                  bodyBytes.Length - recvBodySize, SocketFlags.None);
                                }
                                catch
                                { }

                                // 읽기 실패
                                if (readResult <= 0)
                                {
                                    break;
                                }
                                else
                                {
                                    recvBodySize += readResult;
                                }
                            }

                            // 암호화 키가 있으면 해독
                            NetMessageBody body;
                            if (m_key != null)
                            {
                                body = new NetMessageBody(bodyBytes, m_key);
                            }
                            else
                            {
                                body = new NetMessageBody(bodyBytes);
                            }


                            // 메세지 생성
                            NetMessage msg = new NetMessage(header, body);

                            // 메세지가 유효하면
                            if (msg.IsValid)
                            {
                                // 수신 여부 확인용 목록 확보
                                while (header.SequenceNumber >= m_receivedSeqFlags.Count)
                                {
                                    m_receivedSeqFlags.Add(false);
                                }

                                // 리스트에서 수신 여부를 리셋할 위치를 이동
                                ++m_resetIndexForReceivedSeqFlags;

                                // 범위를 벗어났으면 처음 위치로 이동
                                if (m_resetIndexForReceivedSeqFlags >= this.Sender.MaxBackupSequence)
                                {
                                    m_resetIndexForReceivedSeqFlags = 0;
                                }

                                // 리셋할 위치값이 유효하면 리셋
                                if (m_resetIndexForReceivedSeqFlags >= 0 &&
                                    m_resetIndexForReceivedSeqFlags < m_receivedSeqFlags.Count)
                                {
                                    m_receivedSeqFlags[m_resetIndexForReceivedSeqFlags] = false;
                                }


                                // 정상수신 응답 메세지이면
                                if (header.MessageNumber == (int)NetProtocols.CheckPacket)
                                {
                                    // 정상적으로 수신되었음을 알림.
                                    NetMessageStream reader = new NetMessageStream(msg);
                                    int seqCount            = reader.ReadInt32();

                                    for (int i = 0; i < seqCount; ++i)
                                    {
                                        int seqNum = reader.ReadInt32();
                                        this.Sender.ReceiveNormally(seqNum);
                                    }
                                }
                                else
                                {
                                    // 정상수신 응답 메세지가 아니면

                                    // 정상수신 알림 목록의 첫번째에 들어가는 메세지의 받은 시간을 기록
                                    if (m_receivedSeqList.Count <= 0)
                                    {
                                        m_latestReceiveTime = DateTime.Now;
                                    }

                                    // 정상적으로 수신했음을 알릴 예정으로 목록에 추가
                                    m_receivedSeqList.Add(header.SequenceNumber);

                                    // 정상수신 알림 목록이 일정크기 이상이 되었으면
                                    if (m_receivedSeqList.Count > 16)
                                    {
                                        // 정상수신 알림
                                        this.SendReceivedSeq();
                                    }


                                    // 이전에 받은적이 없는 시퀀스의 메세지이면
                                    if (m_receivedSeqFlags[header.SequenceNumber] == false)
                                    {
                                        // 받은걸로 표시
                                        m_receivedSeqFlags[header.SequenceNumber] = true;


                                        // 키 갱신 메세지이면
                                        if (header.MessageNumber == (int)NetProtocols.ResetKey)
                                        {
                                            // 키 갱신
                                            NetMessageStream reader = new NetMessageStream(msg);
                                            var keyStr = reader.ReadString();

                                            m_key = Enumerable.Range(0, keyStr.Length)
                                                    .Where(x => x % 2 == 0)
                                                    .Select(x => Convert.ToByte(keyStr.Substring(x, 2), 16))
                                                    .ToArray();
                                        }
                                        // 죽으라는 메세지이면
                                        else if (header.MessageNumber == (int)NetProtocols.Die)
                                        {
                                            // 비정상 종료
                                            break;
                                        }
                                        // 일반 메세지이면
                                        else if (header.MessageNumber >= 0)
                                        {
                                            // 버퍼에 여유가 있을때까지 대기한뒤
                                            while (m_messageQueue.Count >= this.MaxMessageCount)
                                            {
                                                Thread.Sleep(16);
                                            }

                                            // 수신목록에 추가
                                            m_messageQueue.Push(msg);
                                        }
                                    }
                                }
                            }
                        }
                    }


                    Thread.Sleep(4);
                }
            }
            catch (IOException)
            { }
            catch (SocketException)
            { }
            catch (ThreadAbortException)
            { }
            catch (ObjectDisposedException)
            {
                m_receiverRun = false;
            }


            // 비정상적인 종료이면
            if (m_receiverRun)
            {
                // 이벤트 발생
                WhenDisconnected();
            }

            m_receiverRun = false;
        }