You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# TcpListener与MySqlConnection运行一段时间后停止接受连接

C#异步Socket服务器网络失效故障排查

我使用C#编写了一个异步Socket服务器,部署在运行Amazon Linux的Lightsail服务器上。该服务器通过TcpListener接受连接,当有客户端连接时启动新线程监听,完成SSL连接初始化后作为在线游戏服务器运行。

服务器正常运行约一天后,会突然出现网络完全失效的情况,故障出现间隔从22小时到一周不等,具体症状如下:

  • 已连接的客户端会突然停止收发数据,日志显示无活动检测代码最终因未收到心跳包将其踢下线。
  • 服务器无法连接本地运行的MySQL数据库(此时仍可通过PHPMyAdmin访问该数据库)。
  • 服务器仍可向文件和控制台写入内容,日志功能正常。

我的代码与常规实现类似,已尝试参考Stack Overflow相关问题的优化方案,但服务器仍在约24小时后出现故障。故障发生前无任何异常日志,导致排查困难。

主循环代码

public void ListenLoop()
{
    TcpListener listener = new TcpListener(IPAddress.Any, 26000);
    listener.Start();

    while (true)
    {
        try
        {
            if (listener.Pending())
            {
                listener.BeginAcceptTcpClient(new AsyncCallback(AcceptConnection), listener);
                Logger.Write(Logger.Level.INFO, "continuing the main loop");
            }
            // Yield so we're not stuck in a busy-loop
            Thread.Sleep(5);
        }
        catch (Exception e)
        {
            Logger.Write(Logger.Level.ERROR, $"Error while waiting for listeners: {e.Message}\n{e.StackTrace}");
        }
    }
}

连接接受相关代码

/// <summary>
/// Finish an async callback but spawn a new thread to handle it if necessary
/// </summary>
/// <param name="ar"></param>
private void AcceptConnection(IAsyncResult ar)
{
    if (ar.CompletedSynchronously)
    {
        // Force the accept logic to run async, to keep our listening
        // thread free.
        Action accept = () => AcceptCallback(ar);
        accept.BeginInvoke(accept.EndInvoke, null);
    } else
    {
        AcceptCallback(ar);
    }
}

private void AcceptCallback(IAsyncResult ar)
{
    try
    {
        TcpListener listener = (TcpListener) ar.AsyncState;
        TcpClient client = listener.EndAcceptTcpClient(ar);
        // If the SSL connection takes longer than 5s we have a problem, and should stop
        client.Client.ReceiveTimeout = 5000;

        // Attempt to get the IP address of the client we're connecting to
        IPEndPoint ipep = (IPEndPoint)client.Client.RemoteEndPoint;
        string ip = ipep.Address.ToString();
        Logger.Write(Logger.Level.INFO, $"Connection begun to {ip}");

        // Authenticate and begin communicating with the client
        SslStream stream = new SslStream(client.GetStream(), false);
        try
        {
            stream.AuthenticateAsServer(
                serverCertificate,
                enabledSslProtocols: System.Security.Authentication.SslProtocols.Tls12,
                clientCertificateRequired: false,
                checkCertificateRevocation: true
                );

            stream.ReadTimeout = 3600000;
            stream.WriteTimeout = 3600000;

            NetworkPlayer player = new NetworkPlayer();
            player.Name = ip;
            player.Connection.Stream = stream;
            player.Connection.Connected = true;
            player.Connection.Client = client;
            stream.BeginRead(player.Connection.Buffer, 0, 1024, new AsyncCallback(ReadCallback), player);
        }
        catch (Exception e)
        {
            Logger.Write(Logger.Level.ERROR, $"Error while starting the connection to {ip}: {e.Message}");
            // The following code just calls stream.Close(); and client.Close(); but sends exceptions to my logger.
            CloseConnectionSafely(client, stream);
        }
    }
    catch (Exception e)
    {
        Logger.Write(Logger.Level.ERROR, $"Error while starting a connection to an unknown user: {e.Message}");
    }
}

内容的提问来源于stack exchange,提问作者OrdiNeu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 00:24:17