2017-09-25 68 views
1

我不熟悉TcpListenersockets,但我有我的Wcf項目的我的App_Code在我的Initializer類中有時會正確執行以下代碼,但第一次正確執行它會顯示我有時出錯,然後正確執行其他沒有模式的。TcpListener.AcceptSocket產生InvalidOperationException

在這行代碼中的錯誤停止:

Socket soc = listener.AcceptSocket(); 

,然後顯示該aditional的信息:

附加信息:未聽力。在調用此方法之前調用Start()方法。

但是正如你所看到的,我在調用listener.AcceptSocket()之前調用start方法()…

我懷疑這是爲了嘗試在WCF項目中啓動一個init守護進程。

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程序,您直接使用SocketTcpListener目前尚不清楚。 WCF的要點是讓它爲你處理網絡I/O。

那就說&hellip;

你所得到的異常,因爲listener所有你的線程和一個或更多的線程之間共享已管理的第一線創造了一個新的TcpListener對象剛過去AcceptSocket(),但它的前稱爲Start()

這真的很好,你有例外。你的代碼很容易運行,沒有例外,如果你運氣不好,然後你會遇到一個更難調試的問題,因爲唯一的症狀是,神祕的是,並不是所有的聽衆都接受任何客戶端。恕我直言,最好是設計代碼,以便你有單獨的對象實例處理每個監聽套接字(並使用 - 靜態成員的值)。這樣,您可以確定每個聽衆都能正確獨立地運行。

但是,你在這裏的代碼可以是固定的,至少相對於異常,通過傳遞正確的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的話題的特定問題,我建議你將它作爲一個新問題發佈。 –