article search result of 'Connection' : 1

  1. 2011.10.16 [C# 서버에서 AS3 클라이언트 비정상 종료 체크하기] (164)

[C# 서버에서 AS3 클라이언트 비정상 종료 체크하기]


TcpServer 에서 얻어온 client = server.AcceptTcpClient(); 

그리고

client.Client.Connected

라는 속성이 있는데 , 이것은 swf 가 종료 되었을때 체크가 불가능 하다.
그래서 예전에는 [한번 연결 , 한번 송수신 , 바로 종료] 의 매커니즘으로 안전적인 연결을 보장했다.

참고 (http://www.scripter.co.kr/entry/TCPSocket-안전한-Socket-연결과-버퍼데이터를-설정한-데이터전송-C-As3)

하지만 계속 연결을 보장해야 하는경우도 있지 않을까...

역시나 문제는 연결이 지속가능한지를 체크하여 소켓 루프를 사용가능한 상태로 만들어야 하는데 방법이 마땅치 않았다. 구지 방법을 찾자면 서로가 지속적으로 소켓을 통해

[서버 : 잘있냐? , 클라이언트 : 잘있다.] 는 연결이 건재함,
[서버 : 잘있냐? , 클라이언트 : ....] 는 연결이 손실됨 , 다시 연결 요청 

와 같이 지속적으로 물어 보는 방법이 있는데 매우 비효율적인 방법 아닌가... 참으로 서버와 클라이언트 , 둘다 득될것이 없는 방법이다.

그러던 와중 방법을 찾아 내었다.

 
while (true)
            {
                // 클라이언트 대기
                trace("wait....");
                TcpClient client;
                try
                {
                    client = server.AcceptTcpClient();
                }
                catch
                {
                    trace("ERR>> 비정상 종료");
                    return;
                }


                //환영 메세지
                byte[] sendByte = StringUTIL.StringToByte("connect Ok");
                client.GetStream().Write(sendByte, 0, sendByte.Length);
                client.GetStream().Flush();

                trace("send!");

                // client.GetStream().ReadByte()를 체크한다. 
                // 만약 연결이 유지 되고 있다면 -1 이 아닐테지만
                // swf 가 비정상 종료 , 혹은 종료 되거나 하면 -1 을 호출하여 
                // 아래의 루프를 벗어날것이다. 그리하여 소켓은 다시 사용 가능한 상태가 된다.    
                while (client.GetStream().ReadByte() != -1)
                {
                    //Console.WriteLine(c + " " + client.GetStream().ReadByte() );
                    
                    if (client.GetStream().DataAvailable)
                    {
                        NetworkStream ns = client.GetStream();
                        ns.Read(headerBuffer, 0, headerBuffer.Length);
                        string header = Encoding.ASCII.GetString(headerBuffer).Trim();
                        trace("header :" + header);

                        if (header == "close")
                        {
                            trace("cloader header!");
                            break;
                        }
                    }
                }
                trace("end!");


위의 코드 처럼 while (client.GetStream().ReadByte() != -1) 를 체크하여 루프를 돌린다면 충분히 체크가 가능하다.

물론 swf , 즉 클라이언트 프로그램이 종료 될때 close() 를 호출하여 서버에 [ 클라이언트 : 나 종료함! ~] 이라고 알려 줘야 하는게 정상이나 , swf 같은경우에는 프로그램이 종료될때 호출할수 있는 이벤트가 없다.
(하지만 AIR 는 있다.)

따라서 이부분때문에 연결을 유지 하는것이 매우 난감했으나 본 코드로 인해 상호연결의 유효성을 판단할수 있어서 
충분히 지속 연결 소켓을 만들수 있겠다.

   


하지만 위의 코드는 문제를 내포 하고 있다.
클라이언트로 받는 바이트를 1 씩 미리읽어 1바이트씩 이동 했다는것인데, 이것때문에 여럿 문제를 야기 한다.
이것의 해결책은 다음에 포스팅 하도록 한다.

그리고

if (client.GetStream().DataAvailable)
                    {

이 .. 문장도 문제가 있다.
Yamecoder 야매코더_
C# 2011.10.16 00:44
Powerd by Tistory, designed by criuce
rss