Exemple #1
0
        public TestResult StartTest()
        {
            Debug.Assert(m_protocol==ProtocolType.Tcp || m_protocol==ProtocolType.Udp);
            m_poller = new SocketPoller();
            m_testResult = new TestResult();
            m_testResult.Protocol = m_protocol;

            // 소켓 준비
            m_requester = Function.CreateSocket(m_protocol,
                                                null,
                                                m_protocol == ProtocolType.Tcp);
            m_testResult.PrivateAddress_1 = (IPEndPoint)m_requester.LocalEndPoint;
            if (m_protocol == ProtocolType.Udp) {
                // UDP는 하나의 소켓으로 모두 처리한다.
                m_poller.Start(m_requester);
            }
            else {
                Function.CreateListenr(m_testResult.PrivateAddress_1,
                                       m_poller,
                                       true);
            }

            // 테스트 수행
            try {
                // Step 1. Filtering Behavior Test
                if (Step1())
                    return m_testResult;

                Debug.Assert(m_testResult.Exist_NAT);
                Debug.Assert(m_testResult.FilteringBehavior != TestResult.Behavior.None);

                // Step 2. Mapping Behavior Test (1)  :  APDM인지 여부를 테스트.
                if (m_testResult.PublicAddress_2 == null) {
                    if (Step2())
                        return m_testResult;
                }

                // Step 3. Mapping Behavior Test (2)  :  EIM인지 ADM인지 여부를 테스트.
                if (m_testResult.MappingBehavior == TestResult.Behavior.None) {
                    Debug.Assert(m_testResult.PublicAddress_1.Equals(m_testResult.PublicAddress_2));
                    if (Step3())
                        return m_testResult;
                }

                Debug.Assert(m_testResult.MappingBehavior != TestResult.Behavior.None);

                // Step 4. Hairpin Test
                Step4();

                // 완료
                m_testResult.Complete = true;
                return m_testResult;
            }
            finally {
                m_poller.Stop();
            }
        }
Exemple #2
0
        public void Start()
        {
            Socket tcpSock = new Socket(AddressFamily.InterNetwork,
                                        SocketType.Stream,
                                        ProtocolType.Tcp);
            Socket udpSock = new Socket(AddressFamily.InterNetwork,
                                        SocketType.Dgram,
                                        ProtocolType.Udp);
            tcpSock.Bind(m_tcp);
            udpSock.Bind(m_udp);

            m_poller = new SocketPoller();
            m_poller.Start_Acceptor(tcpSock);
            m_poller.Start(udpSock);

            m_run = true;
            m_thread = new Thread((object a_data) =>
            {
                while (m_run) {
                    Message msg;
                    Socket sock;
                    IPEndPoint sender;
                    bool isTimeout = ! m_poller.WaitForMessage(Config.Server_Poll_Timeout_Ms,
                                                               out msg,
                                                               out sock,
                                                               out sender);
                    if (isTimeout)
                        continue;

                    string protocolName;
                    if (sock.ProtocolType == ProtocolType.Tcp) {
                        protocolName = "[TCP] ";
                    }
                    else {
                        Debug.Assert(sock.Equals(udpSock));
                        protocolName = "[UDP] ";
                    }

                    bool isHeartbeatMessage = msg.m_contextID == 0;
                    IPEndPoint dst;
                    if (msg.AddressIsEmpty() || isHeartbeatMessage) {
                        // Client로부터 직접 요청을 받은 경우
                        dst = sender;
                        msg.m_address = sender.Address.ToString();
                        msg.m_port = sender.Port;
                    }
                    else {
                        // Client의 요청을 MainServer로부터 전달받은 경우
                        dst = new IPEndPoint(IPAddress.Parse(msg.m_address), msg.m_port);
                        msg.m_address = dst.Address.ToString();
                        msg.m_port = dst.Port;
                    }

                    ++msg.m_contextSeq;
                    msg.m_senderType = Message.SenderType.SubServer;

                    if (isHeartbeatMessage) {
                        // Heartbeat 메시지인 경우
                        if (sock.ProtocolType == ProtocolType.Udp)
                            m_poller.SendTo(sock, dst, msg, false);
                        else
                            m_poller.Send(sock, msg, false);
                    }
                    else {
                        // Request 메시지인 경우
                        string ctxstr = " " + Message.ContextString(msg);
                        Config.OnEventDelegate(protocolName + "Requested from " + sender.ToString() + ctxstr);
                        Config.OnEventDelegate(protocolName + "Response to " + dst.ToString() + ctxstr);

                        if (sock.ProtocolType == ProtocolType.Udp)
                            m_poller.SendTo(sock, dst, msg, false);
                        else {
                            Socket newSocket = new Socket(AddressFamily.InterNetwork,
                                                          SocketType.Stream,
                                                          ProtocolType.Tcp);
                            if (m_poller.ConnectAndSend(newSocket, dst, msg) == false)
                                Config.OnEventDelegate(protocolName + "Failed Response" + ctxstr);
                            m_poller.Close(sock);
                        }
                    }
                }
            });

            m_thread.Start();
        }