TcpListener.AcceptSocket产生InvalidOperationException

时间:2017-09-25 03:18:49

标签: c# wcf tcpclient tcplistener

我不熟悉TcpListenersockets,但我有以下代码,有时在我的Wcf项目的App_Code中的Initializer类中正确执行,但是第一次正确执行它有时会显示错误,然后正确执行其他没有模式的错误。

此行代码中的错误停止:

Socket soc = listener.AcceptSocket();

然后显示这个附加信息:

  

附加信息:不在听力中。在调用此方法之前调用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();
        }
    }

}

1 个答案:

答案 0 :(得分:0)

嗯,不清楚为什么如果这是一个WCF计划,你直接使用SocketTcpListener。 WCF的目的是让它为您处理网络I / O.

那说......

您将收到异常,因为{em>所有线程之间共享了listener字段,并且您的一个或多个线程已设法在AcceptSocket()之后到达TcpListener第一个线程创建了一个新的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字段。

最后一点:你应该从不捕获databaseHandle = ref.child("admin").child(userID!).child("employees").child(self.employeeInfo!).child("attendance").queryOrdered(byChild: fromDateTimeStamp!).queryEnding(atValue: toDateTimeStamp).observe(.childAdded, with: { (snapshot) in for item in snapshot.children { let snap = item as! DataSnapshot let dateKey = snap.key let attendanceDict = snap.value as? [String:AnyObject] self.dateKeyArray += [dateKey] let dateLogin = attendanceDict["currentDate"] as! String self.dateLoginArray += [dateLogin] let timeInTime = attendanceDict["login"] as! String self.loginTimeArray += [timeInTime] let timeOutTime = attendanceDict["logout"] as! String self.logoutTimeArray += [timeOutTime] let breakStartTime = attendanceDict["breakStart"] as! String self.breakStartTimeArray += [breakStartTime] let breakFinishTime = attendanceDict["breakFinish"] as! String self.breakFinishTimeArray += [breakFinishTime] } }) ,除了在代码的一部分中,所有会发生的事情,可选地记录异常,并且过程终止