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

C#开发Windows桌面程序控制Numato以太网继电器无响应求助

问题分析与解决

原C#代码的核心问题

  • 编码逻辑错误:Encoding.GetEncoding(command)完全不符合编码使用规范,这里应该指定UTF-8编码,而非把指令字符串当作编码名称传入。
  • 发送内容不符:你发送的是"u" + '\n',既不是目标指令relay on 1,也没有遵循Java代码里\r\n的换行符要求。
  • 缺少登录验证:设备需要用户名samp和密码samp,但你未完成Telnet登录流程就直接发送指令,会被设备拒绝执行。

修正后的C#实现

完整流程(登录+指令发送)

using System;
using System.Net.Sockets;
using System.Text;
using System.Windows.Forms;

public class RelayController
{
    private TcpClient _tcpClient;
    private NetworkStream _networkStream;

    // 连接设备并完成登录
    public bool ConnectToDevice(string ipAddress, int port = 23)
    {
        try
        {
            _tcpClient = new TcpClient(ipAddress, port);
            _networkStream = _tcpClient.GetStream();
            
            // 等待设备初始化提示(部分设备会输出登录提示符)
            System.Threading.Thread.Sleep(500);
            
            // 发送用户名
            SendRawCommand("samp\r\n");
            // 发送密码
            SendRawCommand("samp\r\n");
            
            return true;
        }
        catch (Exception ex)
        {
            MessageBox.Show($"连接失败: {ex.Message}");
            return false;
        }
    }

    // 发送继电器控制指令
    public void SendRelayCommand(int relayNum, bool isTurnOn)
    {
        string cmdText = isTurnOn ? $"relay on {relayNum}\r\n" : $"relay off {relayNum}\r\n";
        SendRawCommand(cmdText);
    }

    // 底层指令发送方法
    private void SendRawCommand(string command)
    {
        if (_tcpClient == null || !_tcpClient.Connected)
            throw new InvalidOperationException("未连接到继电器设备");

        byte[] cmdBytes = Encoding.UTF8.GetBytes(command);
        _networkStream.Write(cmdBytes, 0, cmdBytes.Length);

        // 可选:读取设备响应,用于调试验证
        // byte[] responseBuffer = new byte[1024];
        // int readLength = _networkStream.Read(responseBuffer, 0, responseBuffer.Length);
        // string response = Encoding.UTF8.GetString(responseBuffer, 0, readLength);
        // MessageBox.Show("设备响应: " + response);
    }

    // 断开连接
    public void Disconnect()
    {
        _networkStream?.Close();
        _tcpClient?.Close();
    }
}

按钮点击事件中的使用示例

private void btnTurnOn_Click(object sender, EventArgs e)
{
    var relayCtrl = new RelayController();
    if (relayCtrl.ConnectToDevice("192.168.1.1"))
    {
        relayCtrl.SendRelayCommand(1, true);
        relayCtrl.Disconnect();
    }
}

关键注意事项

  • 编码一致性:和Java代码保持统一使用UTF-8编码,确保指令字节流与设备预期一致。
  • 换行符规范:必须使用\r\n(CRLF)作为指令结束符,多数Telnet设备不识别单独的\n。
  • 登录顺序:Telnet连接建立后,必须先完成用户名、密码的发送验证,再执行控制指令。
  • 响应调试:建议开启代码中注释的响应读取逻辑,方便排查指令是否被设备正确接收执行。

内容的提问来源于stack exchange,提问作者Mark Ryan Morales

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 20:50:28