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

如何通过Socket/TcpClient维持与服务器的ESTABLISHED连接?

TCP连接维持问题排查与疑问

我已成功与服务器建立连接,通过CMD命令netstat -a -n可查看连接状态,但约21秒后连接会从ESTABLISHED变为CLOSE_WAIT,希望始终维持ESTABLISHED状态。

我先后尝试了两种C#实现方案:

方案1:直接使用Socket

设置KeepAlive后,连接仍会转为CLOSE_WAIT且无异常提示,代码如下:

private void _connect()
{
    var IpEndPoint = new IPEndPoint(IPAddress.Parse("10.10.10.120"), 3000);
    var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
    client.SendTimeout = 60;
    client.ReceiveTimeout = 60;
    try
    {
        client.Connect(IpEndPoint);
        int byteCount = 0;
        byte[] bytes = new byte[256];
        while (true)
        {
            byteCount = client.Receive(bytes);
            if (byteCount == 0) // 未从服务器接收数据时,客户端发送 dummy 数据
            {
                byte[] data_send = Encoding.ASCII.GetBytes("Hi, dummy data");
                client.Send(data_send);
            }
            else // 接收到服务器数据时,写入日志文件
            {
                byte[] byte_rec = new byte[byteCount];
                Buffer.BlockCopy(bytes, 0, byte_rec, 0, byteCount);
                txt_log.Text = Encoding.ASCII.GetString(byte_rec);
            }  
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

方案2:使用TcpClient

连接约20秒后在netstat中无状态显示,出现**"Unable to read data from the transport connection: An established connection was aborted by the software in your host machine"**异常,代码如下:

private void _connect()
{
            TcpClient client1 = new TcpClient();
            try
            {               
                client1.Connect("10.10.10.120", 3000);
                NetworkStream stream1 = client1.GetStream();
                var bytes = new byte[256];
                while (true)
                {
                    int numbyte = stream1.Read(bytes, 0, bytes.Length);
                    if (numbyte == 0)
                    {
                        byte[] data_send = Encoding.ASCII.GetBytes("Hi, dummy data");
                        stream1.Write(data_send, 0, data_send.Length);   
                    }
                    else
                    {
                        byte[] byte_rec = new byte[numbyte];
                        Buffer.BlockCopy(bytes, 0, byte_rec, 0, numbyte);
                        txt_log.Text = Encoding.ASCII.GetString(byte_rec);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
}

优化后情况及疑问

后续优化代码后,无断点运行时可维持连接超10分钟,但调试时发现NetworkStream的DataAvailable首次为true,之后始终为false,添加断点会导致连接断开并抛出上述异常。想了解DataAvailable状态变化的原因及如何彻底解决连接维持问题。优化后的代码如下:

private async void _connect()
  {
            var serverEndpoint = new IPEndPoint(IPAddress.Parse(_ip), _port);
            client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            try
            {
                client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
                client.Connect(serverEndpoint);
                client.NoDelay = true;
                client.SendTimeout = 60000;
                client.ReceiveTimeout = 60000;
                byte[] myReadBuffer = new byte[1024];
                int numberOfBytesRead = 0;
                bool _flag = false;             
                while (true)
                {
                    stream = new NetworkStream(client); // 基于Socket创建流
                    if (stream.CanRead)
                    {
                        do
                        {
                            if (_flag)
                            {
                                numberOfBytesRead = 0;
                                goto receiveskip;
                            }
                            if (numberOfBytesRead == 0) // 先向服务器发送dummy数据
                            {
                                byte[] data_dummy = Encoding.ASCII.GetBytes("dummy_abc");
                                stream.Write(data_dummy, 0, data_dummy.Length);
                                stream.Flush();
                            }
                            numberOfBytesRead = stream.Read(myReadBuffer, 0, myReadBuffer.Length);
                            byte[] bytes_rec = new byte[numberOfBytesRead];
                            Buffer.BlockCopy(myReadBuffer, 0, bytes_rec, 0, numberOfBytesRead);                         
                            // 首次发送dummy_abc后接收服务器数据
                            if(bytes_rec.Length == 14) 
                            {
                                txt_log.Text += Encoding.ASCII.GetString(bytes_rec); // 写入文本框
                            }
                            // 后续接收服务器数据(长度大于14)
                            if (bytes_rec.Length > 14)
                            {
                                byte[] data_rep = Encoding.ASCII.GetBytes("Ok, thank server"); // 客户端回复服务器
                                stream.Write(data_rep, 0, data_rep.Length);
                                stream.Flush();
                                _flag = true;
                                continue;
                            }
                        receiveskip:;
                        }
                        while (stream.DataAvailable);
                    }
                    else
                    {
                        MessageBox.Show("Cannot read from this NetworkStream.");
                    }
                }
            }
            catch (Exception ex)
            {
                stream.Close();
                client.Close();
                MessageBox.Show(ex.Message);
            }
  } 

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 01:20:55