Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# C服务器-这是计时和断开连接的好方法吗?_C#_Multithreading - Fatal编程技术网

C# C服务器-这是计时和断开连接的好方法吗?

C# C服务器-这是计时和断开连接的好方法吗?,c#,multithreading,C#,Multithreading,在我的多线程服务器上,我遇到了连接问题,这些连接不是来自正确的客户端,因此挂起时不受干扰。我不想创建新线程只是为了检查客户端是否在未经授权的情况下连接了一段时间。与此相反,我将此检查添加到ReceiveData线程,如下面的代码所示。您是否发现一些性能问题,或者这是可以接受的?主要的一点是,每次连接客户端并实例化类客户端时,它都会启动秒表。因此,我添加到这个线程条件中——如果时间大于1,并且客户端仍然未被授权,那么它将添加到确定断开连接的客户端列表中。谢谢 编辑:此值为ReceiveData线程

在我的多线程服务器上,我遇到了连接问题,这些连接不是来自正确的客户端,因此挂起时不受干扰。我不想创建新线程只是为了检查客户端是否在未经授权的情况下连接了一段时间。与此相反,我将此检查添加到ReceiveData线程,如下面的代码所示。您是否发现一些性能问题,或者这是可以接受的?主要的一点是,每次连接客户端并实例化类客户端时,它都会启动秒表。因此,我添加到这个线程条件中——如果时间大于1,并且客户端仍然未被授权,那么它将添加到确定断开连接的客户端列表中。谢谢

编辑:此值为ReceiveData线程。我正在使用异步。操作-从tcplistener.beginacept到线程池。我已经更新了代码,让你看到更多

 protected void ReceiveData()
    {
        List<Client> ClientsToDisconnect = new List<Client>();
        List<System.Net.Sockets.Socket> sockets = new List<System.Net.Sockets.Socket>();
        bool noClients = false;
        while (true)
        {
            sockets.Clear();
            this.mClientsSynchronization.TryEnterReadLock(-1);
            try
            {
                for (int i = 0; i < this.mClientsValues.Count; i++)
                {
                    Client c = this.mClientsValues[i];
                    if (!c.IsDisconnected && !c.ReadingInProgress)
                    {
                        sockets.Add(c.Socket);
                    }
                    //clients connected more than 1 second without recieved name are suspect and should be disconnected
                     if (c.State == ClientState.NameNotReceived && c.watch.Elapsed.TotalSeconds > 1)
                         ClientsToDisconnect.Add(c);
                }
                if (sockets.Count == 0)
                {
                    continue;
                }
            }
            finally
            {

                this.mClientsSynchronization.ExitReadLock();
            }
            try
            {
                System.Net.Sockets.Socket.Select(sockets, null, null, RECEIVE_DATA_TIMEOUT);
                foreach (System.Net.Sockets.Socket s in sockets)
                {
                    Client c = this.mClients[s];
                    if (!c.SetReadingInProgress())
                    {
                        System.Threading.ThreadPool.QueueUserWorkItem(c.ReadData);

                    } 
                }
                //remove clients in ClientsToDisconnect
                foreach (Client c in ClientsToDisconnect)
                {
                    this.RemoveClient(c,true);
                }
            }
            catch (Exception e)
            {
                //this.OnExceptionCaught(this, new ExceptionCaughtEventArgs(e, "Exception when reading data."));
            }
        }
    }

我的直觉反应是,如果sockets.Count==0继续,而true加if将导致CPU心痛。为什么不把它放在计时器上或者其他什么东西上,这样这个函数就只需要每隔5秒调用一次?1s屏障真的那么重要吗?

我想我知道你在尝试做什么,我认为更好的方法是在等待区存储新连接,直到它们正确连接

我不是肯定的,但看起来你的代码可能会断开一个有效的连接。如果在检查部分之后建立新连接,并且第二部分花费的时间超过一秒钟,则在验证连接之前,所有计时器都将超时。这将在套接字池和ClientsToDisconnect池中放置新连接。不好的。你会放弃一个当前活跃的连接,混乱就会接踵而至


为了避免这种情况,我将连接的验证与连接的使用分开。这样,您就不会陷入计时问题的泥潭了……您仍然会,但当我们使用线程和套接字时会发生这种情况,并且您确信您正在使用的所有套接字都不会被您关闭。

我希望有更多的时间来写一个正确的答案,但我必须运行。简单地说,不,这不是最好的方法。首先,这是一个毫无理由的紧密循环。您应该研究一个异步套接字模型,并为您的超时模型提供一种使用计时器的方法。很抱歉,我没有编写它-这是ReceiveData线程,我认为必须有whilerun。它是独立的线程,当有数据时,这些数据在线程池中处理。与上面的答案相同-很抱歉,我的帖子不清楚。这是主datarecieve线程,正如您现在看到的-我刚刚发布了整个方法。不能在两者之间创建新连接-我正在处理客户端类列表并使用ReaderWriterLock。套接字仅取自客户端类实例。