버그 해결을 위한 모든 질문을 던져
+1 vote
481 views

반갑습니다~ 이전 하고 글올리는건 처음이네요 ^^

동접이 2~3천 나오는 간단한 [Win2014, c# 닷넷]
"게임용 TCP 어플리케이션 채팅서버" 부분 인데,
잘돌아가다가, 

갑자기 잠잘때나, 밥먹을때나, 걸어가는중일때나
3~4 개월 마다 한번씩(비규칙적으로) 
리스너용 소켓이 외부에서 새로 접속하려는 유저에게
응답이 죽어 버리는 현상이 생기네요. 
 

Thread m_Thread_TCP = null;
Socket m_ServerSocket;         //TCP 리스너
ManualResetEvent allDone = new ManualResetEvent(false);

public void StartServer_TCP()
{
    try
    {
        if (m_Thread_TCP != null)
        {
            m_Thread_TCP.Abort();
        }

        m_Thread_TCP = new Thread(new ThreadStart(ThreadProc_TCP));
        m_Thread_TCP.Start();
    }
    catch (Exception ex)
    {
        return;
    }
}

private void ThreadProc_TCP()  
{
    //중복 포트사용을 할수없기때문에 기존에 소켓이 열려있으면 닫아준다.
    if (m_ServerSocket != null)
    {
        try
        {
            if (m_ServerSocket != null && m_ServerSocket.Connected)
            {
                m_ServerSocket.Shutdown(SocketShutdown.Both);
            }
            m_ServerSocket.Close();
        }
        catch (Exception e)
        {
            return;
        }
    }

    //포트 바인딩을 한다.
    try
    {
        m_ServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

        m_ServerSocket.Bind(new IPEndPoint(IPAddress.Any, int.Parse(this.textBox_APP_PORT.Text)));		
        m_ServerSocket.Listen(10);

        while (true)
        {
            allDone.Reset();
            m_ServerSocket.BeginAccept(new AsyncCallback(OnConnectRequest), m_ServerSocket);
            allDone.WaitOne();
        }
    }
    catch (Exception e)
    {
        try { m_ServerSocket.Close(); } catch { }
    }
}

// 클라이언트로부터 accept가 있을 경우
public void OnConnectRequest(IAsyncResult ar)
{
    try
    {
        Socket listener = (Socket)ar.AsyncState;
        NewConnection(new ClientSocket(listener.EndAccept(ar)));
        allDone.Set();
    }
    catch (Exception e)
    {
    }
}

// 새로운 connection을 만든다.
public void NewConnection(IClientSocket clientSocket, bool _isWeb = false)
{
    Client_st client_new = new Client_st((m_uid++).ToString(), clientSocket);
    client_new.SetupRecieveCallback();
    //===  생략  ====
}


문제가 되는 부분은 어느순간에


- ThreadProc_TCP() 메서드에서
- m_ServerSocket.BeginAccept


이부분으로 유저가 더이상 Accept  되지않는 기현상이 생기네요.
기존에 접속중인 유저들은 아무문제없고, 신규접속만 막히는상황...

내부에 버그라면 어떻게 디버깅으로 풀어보겠는데.
생기는것도 월단위로 간헐적으로 생기고,,,

혹시 
짚히는 부분이 있는분 있으신가요?
이것때문에 숙면을 못해요 ㅠㅆㅠ

asked (24 point) , 481 views

2 answers

+2 votes

일단 코드로만 봤을 경우에는 ThreadProc_TCPOnConnectRequest 함수가 서로 이벤트로 통신하는데 OnConnectRequest의 try 안에서 예외가 나면 allDone.Set이 불리지 않아 루프가 멈출 수 있을 것 같습니다. 아마 catch절이 비어 있어서 예외가 있었는지 확인을 못하신 걸지도 모르겠네요. 

finally를 만들거나 try-catch 바깥에 allDone.Set()을 호출해주는 정도의 조치가 필요해보입니다.

answered (99 point)

네 보시기 불편하실까봐 콘솔 출력부는 전부 제거했는데
allDone.Set()을 호출 하진않았었습니다.

일단 콘솔에 메세지가 뿌려지지 않긴 했었는데, 그래도 모르니 
그러면 그부분에 allDone.Set 이랑 웹훅을 콜하도록 하는걸 추가해서 한번 돌려보겠습니다.
감사합니다.^^

+1 vote
어 저는 고기굽는빵집과는 다르게 코드상에서 new가 실패한게 아닐까 하고 의심이 들어요.

 

m_ServerSocket.BeginAccept(new AsyncCallback(OnConnectRequest), m_ServerSocket);

 

new AsyncCallback 요 부분 하다가 실패가 나는지 확인해보시는건 어떨까 싶어요.

왜냐면 3~4개월에 한번씩이라고 하셨으니까요.

거기다가 저것들이 전부 delete 가 되는지도 사실 잘 모르니까요 흠..

 

라고 쓰다가 보니 C++이 아니라 C# 이였네요;;;
answered (12 point)
아, 감사합니다.

c# 이다보니 그러한 부분까지 의심해보지는 않았네요.

허나, 다들 그 콜백 부분을 지적하셔서,
아예 allDone.WaitOne(); 부분을
allDone.WaitOne(5000); 으로 교체까지 해서 다시 돌려놨습니다.

잘 되면 좋겠네요

버그 해결을 위해 도움을 구하고, 도움을 주세요. 우리는 그렇게 발전합니다.

throw bug 는 프로그래밍에 대한 전분야를 다룹니다. 질문,논의거리,팁,정보공유 모든 것이 가능합니다. 프로그래밍과 관련이 없는 내용은 환영받지 못합니다.

132 질문
224 answers
258 댓글
247 users