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

SocketException求助:目标机器主动拒绝连接,WinForm客户端服务器无法连通

WinForms客户端与服务器端连通解决方案

我明白你现在卡在WinForms客户端和服务器端连通的问题上,查了不少StackOverflow问题但没找到适配的方案——别着急,咱们从你给出的服务器端代码片段入手,一步步梳理可能的问题和改进方向。

你的服务器端代码潜在问题分析

从你提供的代码片段来看,存在几个关键缺失点:

  • 没有启动监听的核心调用listener.Start()
  • TcpListener如果是方法内局部变量,会随方法执行完成被回收,无法持续监听
  • 同步监听会阻塞WinForms UI线程,导致界面假死
  • 缺少完整的异常处理和资源清理逻辑

改进后的服务器端完整代码

首先,在你的WinForms窗体类中声明类级别的TcpListener变量,避免被回收:

private TcpListener _tcpListener;
private bool _isListening = false;

private async void connectButton_Click(object sender, EventArgs e)
{
    // 避免重复点击启动监听
    if (_isListening)
    {
        MessageBox.Show("服务器已在监听状态");
        return;
    }

    try
    {
        // 解析IP地址,增加格式校验
        if (!IPAddress.TryParse(ipBox.Text, out IPAddress ip))
        {
            MessageBox.Show("请输入有效的IP地址");
            return;
        }

        // 初始化监听对象
        _tcpListener = new TcpListener(ip, 8000);
        _tcpListener.Start();
        _isListening = true;
        connectButton.Text = "停止监听";
        MessageBox.Show("服务器启动监听成功");

        // 异步循环接受客户端连接,避免阻塞UI
        while (_isListening)
        {
            TcpClient client = await _tcpListener.AcceptTcpClientAsync();
            // 开启新线程处理客户端通信,避免阻塞监听循环
            _ = HandleClientCommunication(client);
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show($"服务器启动失败:{ex.Message}");
        CleanupListener();
    }
}

// 处理客户端通信的方法
private async Task HandleClientCommunication(TcpClient client)
{
    try
    {
        using (NetworkStream stream = client.GetStream())
        {
            byte[] buffer = new byte[1024];
            int bytesRead;
            // 读取客户端发送的数据
            while ((bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length)) > 0)
            {
                string receivedData = Encoding.UTF8.GetString(buffer, 0, bytesRead);
                // 在UI线程更新信息,避免跨线程操作异常
                Invoke(new Action(() =>
                {
                    logTextBox.AppendText($"收到客户端消息:{receivedData}{Environment.NewLine}");
                }));

                // 可选:回复客户端
                string response = $"服务器已收到消息:{receivedData}";
                byte[] responseBytes = Encoding.UTF8.GetBytes(response);
                await stream.WriteAsync(responseBytes, 0, responseBytes.Length);
            }
        }
    }
    catch (Exception ex)
    {
        Invoke(new Action(() =>
        {
            logTextBox.AppendText($"客户端通信异常:{ex.Message}{Environment.NewLine}");
        }));
    }
    finally
    {
        client.Close();
    }
}

// 清理监听资源的方法
private void CleanupListener()
{
    _isListening = false;
    _tcpListener?.Stop();
    _tcpListener = null;
    connectButton.Text = "启动监听";
}

// 窗体关闭时清理资源
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    CleanupListener();
}

对应客户端代码示例

private async void connectToServerButton_Click(object sender, EventArgs e)
{
    try
    {
        using (TcpClient client = new TcpClient())
        {
            // 连接服务器(替换为服务器的IP和端口)
            await client.ConnectAsync(serverIpBox.Text, 8000);
            MessageBox.Show("成功连接到服务器");

            using (NetworkStream stream = client.GetStream())
            {
                // 发送消息到服务器
                string message = messageTextBox.Text;
                byte[] messageBytes = Encoding.UTF8.GetBytes(message);
                await stream.WriteAsync(messageBytes, 0, messageBytes.Length);

                // 读取服务器回复
                byte[] buffer = new byte[1024];
                int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);
                string response = Encoding.UTF8.GetString(buffer, 0, bytesRead);
                MessageBox.Show($"服务器回复:{response}");
            }
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show($"连接服务器失败:{ex.Message}");
    }
}

关键注意事项

  • 端口与防火墙:确保服务器的8000端口未被占用,且Windows防火墙允许该端口的入站/出站连接
  • IP地址正确性:本地测试可以用127.0.0.1,局域网测试需使用服务器的实际局域网IP(比如192.168.x.x)
  • 跨线程UI操作:WinForms不允许非UI线程操作控件,所以在HandleClientCommunication中用Invoke更新UI
  • 资源清理:务必在停止监听或窗体关闭时调用Stop()释放TcpListener资源,避免端口占用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:21:18