2011-04-29 5 views
3

내 응용 프로그램은 Windows가 종료되는 것을 방지하지만 항상 일부 컴퓨터에서만 종료됩니다. 약간 디버깅하기가 까다 롭습니다. 내 TCP 서버 때문인 것 같아. 그것은 비동기 서버이며, 내 응용 프로그램은 CloseReason == WindowsShutDown을 처리합니다. 이 경우 응용 프로그램이 프로세스로 실행 중이지만 작업 표시 줄/시스템 트레이에서 액세스 할 수 없습니다.Shutdown (때때로)에서 C# 응용 프로그램이 종료되지 않습니다.

누군가 내 서버 코드로 명백한 문제를 볼 수 있는지 궁금합니다.

다음은 내 서버 코드입니다. Stop() 메서드는 기본 폼의 Close() 이벤트에서 호출됩니다. (소켓이 연결되지 않아 허용 된 데이터를주고받을

요청을하고 : 호건에

public class MantraServer 
    { 
     protected int portNumber; 
     private bool ShuttingDown = false; 

     //the main socket the server listens to 
     Socket listener; 

     //Constructor - Start a server on the given IP/port 
     public MantraServer(int port, IPAddress IP) 
     { 
      this.portNumber = port; 
      Start(IP); 
     } 

     /// 
     /// Description: Start the threads to listen to the port and process 
     /// messages. 
     /// 
     public void Start(IPAddress IP) 
     { 
      try 
      { 
       //We are using TCP sockets 
       listener = new Socket(AddressFamily.InterNetwork, 
              SocketType.Stream, 
              ProtocolType.Tcp); 

       //Assign the any IP of the machine and listen on port number 3000 
       IPEndPoint ipEndPoint = new IPEndPoint(IP, 3000); 

       //Bind and listen on the given address 
       listener.Bind(ipEndPoint); 
       listener.Listen(10); 

       //Accept the incoming clients 
       listener.BeginAccept(new AsyncCallback(OnAccept), listener); 
      } 
      catch (Exception ex) 
      { 
       MessageBox.Show(ex.Message, "MANTRA Network Start Error", 
        MessageBoxButtons.OK, MessageBoxIcon.Error); 
      } 
     } 

     /// Decription: Stop the threads for the port listener. 
     public bool Stop() 
     { 
      try 
      { 
       ShuttingDown = true; 
       listener.Shutdown(SocketShutdown.Both); 
       listener.Close(); 
       listener = null; 
       System.Threading.Thread.Sleep(500); //wait for half second while the server closes 
       return true; 
      } 
      catch (Exception) 
      { 
       return false; 
      } 
     } 

     /// 
     /// Decription: Call back method to accept new connections. 
     /// <param name="ar">Status of an asynchronous operation.</param> 
     private void OnAccept(IAsyncResult ar) 
     { 
      try 
      { 
       if (!ShuttingDown) 
       { 
        MantraStatusMessage InMsg = new MantraStatusMessage(); 
        InMsg.Socket = ((Socket)ar.AsyncState).EndAccept(ar); 
        //Start listening for more clients 
        listener.BeginAccept(new AsyncCallback(OnAccept), listener); 

        //Once the client connects then start receiving the commands from them 
        InMsg.Socket.BeginReceive(InMsg.buffer, 0, InMsg.buffer.Length, SocketFlags.None, 
         new AsyncCallback(OnReceive), InMsg); 
       } 
      } 
      catch (Exception ex) 
      { 
       MessageBox.Show(ex.Message, "MANTRA Network Accept Error", 
        MessageBoxButtons.OK, MessageBoxIcon.Error); 
      } 
     } 

     /// 
     /// Receives the data, puts it in a buffer and checks if we need to receive again. 
     public void OnReceive(IAsyncResult result) 
     { 
      MantraStatusMessage InMsg = (MantraStatusMessage)result.AsyncState; 
      int read = InMsg.Socket.EndReceive(result); 
      if (read > 0) 
      { 
       for (int i = 0; i < read; i++) 
       { 
        InMsg.TransmissionBuffer.Add(InMsg.buffer[i]); 
       } 
       //we need to read again if this is true 
       if (read == InMsg.buffer.Length) 
       { 
        InMsg.Socket.BeginReceive(InMsg.buffer, 0, InMsg.buffer.Length, SocketFlags.None, OnReceive, InMsg); 
        Console.Out.WriteLine("Message Too big!"); 
       } 
       else 
       { 
        Done(InMsg); 
       } 
      } 
      else 
      { 
       Done(InMsg); 
      } 
     } 

     /// 
     /// Deserializes and outputs the received object 
     public void Done(MantraStatusMessage InMsg) 
     { 
      Console.Out.WriteLine("Received: " + InMsg.msg); 
      MantraStatusMessage received = InMsg.DeSerialize(); 
      Console.WriteLine(received.msg.Message); 
     } 
    } 

편집

감사합니다, 호출에 좀 더 정보) (닫는 sendto 호출을 사용하여 데이터 그램 소켓을 보낼 때) 주소가 제공되지 않았습니다.

아직 무엇을 의미하는지 확실하지 않습니다.

답변

1

Windows 이벤트 로그에 로깅을 추가하여 현재 진행중인 작업을 확인해야합니다.

시작하기 가장 좋은 장소는 false를 반환하는 catch입니다 (이로 인해 Windows가 종료되지 않습니다.) 이유를 기록하면 이벤트 로그를보고 서비스가 ' 닥쳐.

+0

감사합니다 호간 - Listener.ShutDown() 호출이 예외를 생성하는 것처럼 보입니다. 왜 이런 일이 일어나는지 모르겠다. 테스트 중에는 아직 아무런 데이터도 보내거나 받아서는 안됩니다.이 호출은 위에있는 EDIT처럼 오류를 생성합니다 ... – Simon

+0

'if (listener.connected) listener.ShutDown()와 같은 오류를 내고있는 문장을 래핑 할 수 있습니까?); '? – Hogan

+0

예, Disconnect()를 시도했지만 소켓이 연결되지 않았습니다. 이제 조건부 종료()를 시도하고 있습니다. 이것이 내 문제를 해결하는지 알 수 있습니다. 환호 – Simon

1

항상이어야합니다. 콜백이 발생할 때 비동기 메서드에 대해 EndXXX 대응 메서드를 호출해야합니다. 당신은이 작업을 수행하는 데 실패 :

InMsg.Socket = ((Socket)ar.AsyncState).EndAccept(ar); 

그것이 !shuttingDown 블록에 살고 있기 때문이다. 전화 해 ... 오류를 잡아라.

+0

고마워, 고소 할 것이다. – Simon

관련 문제