2017-09-25 13 views
1

나는 TcpListenersockets을 알지 못한다.하지만 때때로 내 Initializer 클래스에서 내 Wcf 프로젝트의 App_Code에서 올바르게 실행되는 다음 코드를 가지고있다. 때때로 오류가 발생하고 패턴없이 다른 패턴을 올바르게 실행합니다.TcpListener.AcceptSocket produce InvalidOperationException

이 줄을 코드에서 오류 중지 :

추가 정보 : 다음

Socket soc = listener.AcceptSocket(); 

그리고이이 추가적으로 정보를 표시하지 듣기에. 이 메서드를 호출하기 전에 Start() 메서드를 호출하십시오.

그러나 내가 listener.AcceptSocket() & hellip 전에 start 메소드를 호출하는 것을 볼 수 있습니다.

나는 이것이 WCF 프로젝트에서 init 데몬을 시작하려고 시도한 것으로 의심된다. 이것은 WCF 프로그램의 경우, 직접 Socket 또는 TcpListener을 사용하는 이유

public static void AppInitialize() 
{ 
    // This will get called on startup 
    new Initializer().StartListener(); 
} 

static TcpListener listener; 
const int LIMIT = 5; //5 concurrent clients 
private void StartListener() 
{ 
    List<int> puertos = new List<int>(); 

    puertos.Add(5494); 
    puertos.Add(5495); 
    puertos.Add(5496); 
    puertos.Add(5497); 

    foreach (int puerto in puertos) 
    { 
     IPAddress localAddr = IPAddress.Parse(ConfigurationManager.AppSettings["ServerIP"]); 
     listener = new TcpListener(localAddr, puerto); 
     listener.Start(); 

     for (int i = 0; i < LIMIT; i++) 
     { 
      Thread t = new Thread(new ThreadStart(Service)); 
      t.Start(); 
     } 
    } 

} 

private void Service() 
{ 
    while (true) 
    { 
     //Error happen hear, but listener.Start execute before... . 
     Socket soc = listener.AcceptSocket(); 

     try 
     { 

      byte[] resp = new byte[2000]; 
      var memStream = new MemoryStream(); 
      var bytes = 0; 

      NetworkStream s = new NetworkStream(soc); 
      StreamReader sr = new StreamReader(s); 

      while (true) 
      { 
       string trama = ""; 
       if (s.CanRead) 
       { 
        do 
        { 
         bytes = s.Read(resp, 0, resp.Length); 
         trama = Util.Util.ByteArrayToHexString(resp); 
        } 
        while (s.DataAvailable); 
       } 

       if (trama == "" || trama == null) break; 

      } 
      s.Close(); 
     } 
     catch (Exception e) 
     { 
     } 
     finally 
     { 
      soc.Close(); 
     } 
    } 

} 

답변

0

글쎄, 그것은 분명하지 않다. WCF의 요점은 네트워크 I/O를 처리하도록하는 것입니다.

That said & hellip; 그것의 이전

당신은 listener 필드가 당신의 스레드 당신의 스레드 모든 하나 이상의 공유하기 때문에 첫 번째 스레드가 새로운 TcpListener 개체를 만든 직후 AcceptSocket()를 얻을 수있게되었다 예외를 받고되지만, Start()이라고합니다.

실제로 예외가 발생했습니다. 당신의 코드는 예외없이 쉽게 실행될 수 있습니다. 만약 당신이 충분히 불행했다면, 디버깅하는 것이 더 어려울 것입니다. 유일한 증상은 신비하게도, 모든 청취자가 모든 클라이언트를 받아들이는 것이 아니기 때문입니다.

IMHO, 각 청취 소켓을 처리하는 별도의 객체 인스턴스를 가질 수 있도록 코드를 설계하는 것이 가장 좋습니다 (값에 대해서는 비 - - 정적 멤버 사용). 그렇게하면 각 청취자가 정확하고 독립적으로 작동하는지 확인할 수 있습니다.

하지만, 당신이 여기있는 코드는 각 스레드에 올바른 TcpListener 객체를 전달하여, 적어도 예외에 대한 고정 할 수 있습니다

private void StartListener() 
{ 
    List<int> puertos = new List<int>(); 

    puertos.Add(5494); 
    puertos.Add(5495); 
    puertos.Add(5496); 
    puertos.Add(5497); 

    foreach (int puerto in puertos) 
    { 
     IPAddress localAddr = IPAddress.Parse(ConfigurationManager.AppSettings["ServerIP"]); 
     TcpListener listener = new TcpListener(localAddr, puerto); 
     listener.Start(); 

     for (int i = 0; i < LIMIT; i++) 
     { 
      Thread t = new Thread(() => Service(listener)); 
      t.Start(); 
     } 
    } 

} 

private void Service(TcpListener listener) 
{ 
    while (true) 
    { 
     Socket soc = listener.AcceptSocket(); 

     try 
     { 

      byte[] resp = new byte[2000]; 
      var memStream = new MemoryStream(); 
      var bytes = 0; 

      NetworkStream s = new NetworkStream(soc); 
      StreamReader sr = new StreamReader(s); 

      while (true) 
      { 
       string trama = ""; 
       if (s.CanRead) 
       { 
        do 
        { 
         bytes = s.Read(resp, 0, resp.Length); 
         trama = Util.Util.ByteArrayToHexString(resp); 
        } 
        while (s.DataAvailable); 
       } 

       if (trama == "" || trama == null) break;  
      } 
      s.Close(); 
     } 
     catch (Exception e) { } 
     finally 
     { 
      soc.Close(); 
     } 
    } 
} 

static TcpListener listener; 필드를 제거해야합니다.

마지막 주 : 당신이해야 일어날 모든 선택적 예외가 기록되고 프로세스가 종료되고 있다는 것입니다 코드의 일부를 제외하고 결코 캐치 Exception.

+0

니스, 이것은 내 다른 가정, 스레드의 나쁜 사용, 지금 나는 WCF 중요하지 않습니다 여기, 감사합니다. –

+1

_ "지나치게 광범위하게 보이는 스레드에 대한 정보를 좀 더 보내 주시겠습니까?" Stack Overflow에 대한 주제가 될 스레드에 대해 _specific_ 질문이있는 경우 새로운 질문으로 게시하는 것이 좋습니다. –