Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

急救!远程主机强迫关闭了一个现有的连接。 #768

Open
loveyeguo opened this issue Dec 16, 2024 · 14 comments
Open

急救!远程主机强迫关闭了一个现有的连接。 #768

loveyeguo opened this issue Dec 16, 2024 · 14 comments

Comments

@loveyeguo
Copy link

此代码:

   private async Task KeepAccept(Socket listenSocket)
   {
       while (!_cancellationTokenSource.IsCancellationRequested)
       {
           try
           {
               var client = await listenSocket.AcceptAsync().ConfigureAwait(false);
               OnNewClientAccept(client);
           }
           catch (Exception e)
           {
               if (e is ObjectDisposedException || e is NullReferenceException)
                   break;
               
               if (e is SocketException se)
               {
                   var errorCode = se.ErrorCode;

                   //The listen socket was closed
                   if (errorCode == 125 || errorCode == 89 || errorCode == 995 || errorCode == 10004 || errorCode == 10038)
                   {
                       break;
                   }
               }
               
               _logger.LogError(e, $"Listener[{this.ToString()}] failed to do AcceptAsync");
               continue;
           }
       }

       _stopTaskCompletionSource.TrySetResult(true);
   } 

目前客户端有200多个,运行几分钟后,程序一直报错:
Listener[Ip=Any, Port=1799, Security=None, Path=, BackLog=0, NoDelay=False] failed to do AcceptAsync远程主机强迫关闭了一个现有的连接。
此时测试程序端口仍然能够正常连接并传输数据,只是一直报错而已。但运行5-6小时后,新的客户端将无法再次连接。
我使用老版1.6版本,同样监听此端口,报错也有,但是运行一天以后,新的客户端依然可以正常连接。
请问如何解决? 谢谢大佬!

@wj8400684
Copy link
Contributor

会不会是你电脑问题

@loveyeguo
Copy link
Author

不会

@loveyeguo
Copy link
Author

我已经测试了好几遍了,确定是supersocket程序本身bug。

@wj8400684
Copy link
Contributor

建议写个最小demo复现

@loveyeguo
Copy link
Author

直接用源码侦听就复现了,没有写任何逻辑代码,就侦听两个端口。运行5-6个小时,新的客户端无法再次连接。现在我暂时修复了这个bug : 修改代码如下:

 public bool Start()
        {
            var options = Options;

            try
            {
                if (options.Security != SslProtocols.None && options.CertificateOptions != null)
                {
                    options.CertificateOptions.EnsureCertificate();
                }

                var listenEndpoint = options.GetListenEndPoint();
                var listenSocket = _listenSocket = new Socket(listenEndpoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                listenSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
                listenSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true);
                listenSocket.ReceiveTimeout = 10000; // 设置为10秒
                listenSocket.SendTimeout = 10000; // 设置为10秒
                listenSocket.LingerState = new LingerOption(false, 0);

                if (options.NoDelay)
                    listenSocket.NoDelay = true;
                
                listenSocket.Bind(listenEndpoint);
                listenSocket.Listen(options.BackLog);

                IsRunning = true;

                _cancellationTokenSource = new CancellationTokenSource();

                KeepAccept(listenSocket).DoNotAwait();
                return true;
            }
            catch (Exception e)
            {
                _logger.LogError(e, $"The listener[{this.ToString()}] failed to start.");
                return false;
            }
        }

主要就是要在原有代码上增加如下三行:

listenSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true);
                listenSocket.ReceiveTimeout = 10000; // 设置为10秒
                listenSocket.SendTimeout = 10000; // 设置为10秒

@loveyeguo
Copy link
Author

原有bug复现大致方法: 让大量tcp客户端不断连接然后断开,tcp服务端在运行几个小时后无法再次连接。

@wj8400684
Copy link
Contributor

那这跟supersocket没啥关系呀 应该是你端口耗尽了

@loveyeguo
Copy link
Author

不是啊,诶,你没完全看我写的。 我都说这么详细了。同一台服务器,用1.6版本,没有问题。用最新版本,出现问题。 目前加了那三行代码,暂时没有出现问题。 麻烦完整看一遍我的描述!

@wj8400684
Copy link
Contributor

解决就行

@loveyeguo
Copy link
Author

我这只是临时解决办法,实际情况错误一直在报,我也不懂啥时候就崩溃了,请问你也是联合开发作者吗? 有空可以关注下这个问题!

@chucklu
Copy link
Contributor

chucklu commented Dec 18, 2024

Please provide the source code of the demo, including both client and server code, and push to your own git repository(maybe you can create a new git repository under your GitHub account)

@loveyeguo
Copy link
Author

模拟不了客户端,客户端是rtu采集模块,200多个,我不清楚客户端做了什么操作,就会引起服务器的上述错误。

@loveyeguo
Copy link
Author

总而言之,只要引起服务端上诉代码报错: 远程主机强迫关闭现有连接,其他服务端代码不要任何逻辑,只负责侦听端口。即可重现bug

@wj8400684
Copy link
Contributor

写个简易demo复现

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants