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

C# TCP客户端连接安卓服务器遭拒,目标对接NodeMCU ESP8266

解决TCP客户端连接时“目标机器主动拒绝连接”的问题

首先,这个错误No connection could be made as the target machine actively refused it本质上是你的Windows客户端无法和安卓上的TCP服务器建立握手,大概率是服务器端没正确监听,或者网络/配置层面有问题,再加上你的客户端代码也有一些需要调整的地方,咱们一步步来解决:

一、先排查最常见的环境/服务器端问题

这些是最容易踩坑的点,先排除了再看代码:

  • 确认安卓服务器的监听配置:
    安卓端的TCP服务器必须监听0.0.0.0(允许所有IP访问)或者你的安卓设备在局域网内的实际IP(比如192.168.43.142),绝对不能只监听127.0.0.1(只能本地访问)。另外要确认服务器确实在你指定的端口监听——80端口经常被HTTP服务占用,建议换个不常用的端口比如8888试试,避免端口冲突。
  • 检查网络连通性:
    确保你的Windows电脑和安卓设备在同一局域网(比如连同一个WiFi,或者安卓开热点Windows连上去)。先在Windows的命令行里ping安卓的IP:ping 192.168.43.142,如果ping不通,说明网络本身有问题,先解决网络连通。
  • 防火墙/安全软件拦截:
    关闭Windows的防火墙(或者给你的窗体应用添加允许联网的规则),同时关闭安卓端的防火墙/安全软件,防止它们拦截TCP连接。
  • 确认服务器正在运行:
    安卓端的TCP服务器应用必须处于前台运行状态,有些安卓系统会后台杀进程,导致服务器停止监听。

二、修正你的C#客户端代码中的问题

你的代码基于微软的示例,但有几个不适合Windows窗体应用的地方,调整后能避免很多潜在问题:

1. 避免使用static Socket和全局状态

你把client、remoteEP等都声明为static,在窗体应用里容易出现生命周期混乱(比如多次点击连接按钮会重复操作同一个Socket)。建议把这些实例变量放到Form类的非static成员里。

2. 使用专门的状态类代替Form作为Receive的状态对象

用Form实例作为异步回调的状态对象很容易引发线程问题(因为WinForm控件只能在UI线程操作),应该创建一个单独的StateObject类来保存Socket和缓冲区。

3. 正确处理ManualResetEvent的重置

每次异步操作前要重置ManualResetEvent,否则第一次操作后事件一直处于触发状态,后续操作会直接跳过等待。

4. 断开连接时先判断Socket状态

避免在Socket未连接时调用Shutdown/Close,引发异常。

修正后的代码

namespace nodemcu_connection_test
{
    public partial class Form1 : Form
    {
        // 非static的客户端Socket,避免全局状态混乱
        private Socket _clientSocket = null;
        private const int BufferSize = 256;
        private const int Port = 8888; // 建议换个非80的端口
        private readonly string _serverIp = "192.168.43.142";
        private readonly IPEndPoint _remoteEP;

        // ManualResetEvent实例,每次使用前要重置
        private readonly ManualResetEvent _connectDone = new ManualResetEvent(false);
        private readonly ManualResetEvent _sendDone = new ManualResetEvent(false);
        private readonly ManualResetEvent _receiveDone = new ManualResetEvent(false);
        private string _response = string.Empty;

        public Form1()
        {
            InitializeComponent();
            _remoteEP = new IPEndPoint(IPAddress.Parse(_serverIp), Port);
        }

        private void connect_Click(object sender, EventArgs e)
        {
            StartClient();
        }

        private void disconnect_Click(object sender, EventArgs e)
        {
            // 先判断Socket是否已连接,再释放资源
            if (_clientSocket != null && _clientSocket.Connected)
            {
                try
                {
                    _clientSocket.Shutdown(SocketShutdown.Both);
                }
                catch
                {
                    // 忽略关闭时的异常
                }
                _clientSocket.Close();
                _clientSocket = null;
                MessageBox.Show("已断开连接");
            }
        }

        private void stopreceive_Click(object sender, EventArgs e)
        {
            if (_clientSocket != null && _clientSocket.Connected)
            {
                Send("READSTOP");
            }
        }

        private void startreceive_Click(object sender, EventArgs e)
        {
            if (_clientSocket != null && _clientSocket.Connected)
            {
                Send("READSTART");
                Receive();
                // 更新UI要回到UI线程,避免跨线程异常
                Invoke((Action)(() =>
                {
                    textBox1.Text += _response + "\n";
                }));
            }
        }

        private void StartClient()
        {
            try
            {
                // 先关闭旧的Socket(如果存在)
                disconnect_Click(null, null);

                // 创建新的TCP Socket
                _clientSocket = new Socket(IPAddress.Parse(_serverIp).AddressFamily, 
                    SocketType.Stream, ProtocolType.Tcp);

                // 重置连接事件
                _connectDone.Reset();
                // 开始异步连接
                _clientSocket.BeginConnect(_remoteEP, ConnectCallback, _clientSocket);
                // 等待连接完成(设置5秒超时,避免无限等待)
                if (_connectDone.WaitOne(5000))
                {
                    MessageBox.Show("连接成功");
                }
                else
                {
                    MessageBox.Show("连接超时");
                    _clientSocket.Close();
                    _clientSocket = null;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"连接失败:{ex.Message}");
            }
        }

        private void ConnectCallback(IAsyncResult ar)
        {
            try
            {
                Socket client = (Socket)ar.AsyncState;
                client.EndConnect(ar);
                Console.WriteLine("Socket connected to {0}", client.RemoteEndPoint.ToString());
                _connectDone.Set();
            }
            catch (Exception ex)
            {
                MessageBox.Show($"连接回调异常:{ex.Message}");
                _connectDone.Set(); // 即使失败也要触发事件,避免死等
            }
        }

        private void Receive()
        {
            try
            {
                if (_clientSocket == null || !_clientSocket.Connected)
                    return;

                // 使用专门的状态对象
                StateObject state = new StateObject();
                state.WorkSocket = _clientSocket;

                _receiveDone.Reset();
                _clientSocket.BeginReceive(state.Buffer, 0, BufferSize, 0, ReceiveCallback, state);
                _receiveDone.WaitOne();
            }
            catch (Exception ex)
            {
                MessageBox.Show($"接收启动失败:{ex.Message}");
            }
        }

        private void ReceiveCallback(IAsyncResult ar)
        {
            try
            {
                StateObject state = (StateObject)ar.AsyncState;
                Socket client = state.WorkSocket;

                int bytesRead = client.EndReceive(ar);
                if (bytesRead > 0)
                {
                    state.Sb.Append(Encoding.ASCII.GetString(state.Buffer, 0, bytesRead));
                    // 继续接收剩余数据
                    client.BeginReceive(state.Buffer, 0, BufferSize, 0, ReceiveCallback, state);
                }
                else
                {
                    if (state.Sb.Length > 0)
                    {
                        _response = state.Sb.ToString();
                    }
                    _receiveDone.Set();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"接收回调异常:{ex.Message}");
                _receiveDone.Set();
            }
        }

        private void Send(string data)
        {
            try
            {
                if (_clientSocket == null || !_clientSocket.Connected)
                    return;

                byte[] byteData = Encoding.ASCII.GetBytes(data);
                _sendDone.Reset();
                _clientSocket.BeginSend(byteData, 0, byteData.Length, 0, SendCallback, _clientSocket);
                _sendDone.WaitOne();
            }
            catch (Exception ex)
            {
                MessageBox.Show($"发送失败:{ex.Message}");
            }
        }

        private void SendCallback(IAsyncResult ar)
        {
            try
            {
                Socket client = (Socket)ar.AsyncState;
                int bytesSent = client.EndSend(ar);
                Console.WriteLine("Sent {0} bytes to server.", bytesSent);
                _sendDone.Set();
            }
            catch (Exception ex)
            {
                MessageBox.Show($"发送回调异常:{ex.Message}");
                _sendDone.Set();
            }
        }

        // 专门的异步操作状态类,避免直接用Form实例引发线程问题
        private class StateObject
        {
            public Socket WorkSocket { get; set; } = null;
            public byte[] Buffer { get; set; } = new byte[BufferSize];
            public StringBuilder Sb { get; set; } = new StringBuilder();
        }
    }
}

三、针对NodeMCU(ESP8266)的额外注意事项

等你搞定安卓服务器的测试后,切换到NodeMCU时还要注意:

  • NodeMCU的TCP服务器要监听WiFi.localIP()对应的地址,或者0.0.0.0(允许所有IP访问)
  • 确保NodeMCU和Windows在同一局域网,并且NodeMCU的WiFi连接正常
  • NodeMCU的端口不要被其他设备占用,建议用8888、9999这类非知名端口
  • 查看NodeMCU的串口输出,确认服务器是否正常启动并监听指定端口

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:21:07