2017-09-25 61 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的话题的特定问题,我建议你将它作为一个新问题发布。 –