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

.NET Framework 4 WinForm Tcp服务端检测客户端断开实现问题

问题核心原因

你当前的代码采用短连接逻辑,服务端收到客户端注册请求并返回响应后,就主动关闭了Socket连接,双方没有保持长连接,自然无法感知客户端后续的离线状态。同时原有服务端代码存在多客户端连接时Socket实例被覆盖的线程安全问题。以下是可直接运行的修改方案:


IpServer 完整修改后代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;

namespace IpServer
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        TcpListener tcplist;
        private void init()
        {
            IPAddress ip = IPAddress.Parse("127.0.0.1");
            tcplist = new TcpListener(ip,5050);
            tcplist.Start();
            while (true)
            {
                // 直接将连接的Socket传入线程,避免类变量被多线程覆盖
                Socket clientSocket = tcplist.AcceptSocket();
                Thread t = new Thread(() => replay(clientSocket));
                t.IsBackground = true;
                t.Start();
            }
        }
        private void replay(Socket sc)
        {
            NetworkStream ns = new NetworkStream(sc);
            StreamReader reader = new StreamReader(ns);
            StreamWriter writer = new StreamWriter(ns) { AutoFlush = true };
            string str = "";
            string response = "";
            try 
            { 
                str = reader.ReadLine(); 
                if (str == "register")
                {
                    this.Invoke(new Action(() => {
                        MessageBox.Show("客户端注册成功");
                    }));
                }
                response = "registeredSucss,";
                writer.WriteLine(response);

                // 长连接保持循环,持续检测客户端状态
                while (sc.Connected)
                {
                    // 读返回null说明客户端主动断开连接
                    var heartBeat = reader.ReadLine();
                    if (heartBeat == null) break;
                }
            }
            catch 
            {
                // 连接异常断开触发
            }
            finally
            {
                // 跨线程调用UI要使用Invoke
                this.Invoke(new Action(() => {
                    MessageBox.Show("Client Is disconnect");
                }));
                ns.Close();
                sc.Close();
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Thread t = new Thread(new ThreadStart(init));
            t.IsBackground = true;
            t.Start();
            MessageBox.Show("Server run!!");
            button1.Enabled = false;
        }
    }
}

IpClient 完整修改后代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.IO;

namespace IpClient
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            // 绑定窗体关闭事件,关闭时主动断开连接
            this.FormClosing += Form1_FormClosing;
        }
        TcpClient tcp;
        NetworkStream ns;
        StreamReader reader;
        StreamWriter writer;
        string str = "";

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                tcp = new TcpClient("127.0.0.1",5050);
                tcp.ReceiveBufferSize = 25000;
                tcp.NoDelay = true;
                ns = tcp.GetStream();
                reader = new StreamReader(ns);
                writer = new StreamWriter(ns) { AutoFlush = true };
                writer.WriteLine("register");
                str = reader.ReadLine();
                string[] strsplit = null;
                strsplit = str.Split(',');
                if (strsplit[0] != "registeredSucss")
                {
                    MessageBox.Show("Not connected");
                }
                else
                {
                    MessageBox.Show("Your connected");
                }
                // 不再主动关闭连接,保持长连接
            }
            catch
            {
                MessageBox.Show("连接服务端失败");
            }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            // 窗体关闭时主动释放连接,触发服务端断开检测
            if (tcp != null && tcp.Connected)
            {
                tcp.Close();
            }
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 07:45:03