【问题标题】:Can't get TCP message无法获取 TCP 消息
【发布时间】:2021-09-06 21:54:12
【问题描述】:

嗨,我对此有点陌生,简短的故事是我有一个充当 TCP 服务器的设备,我测试了 带有Hercules Tool 的设备按预期工作,问题出在我的代码中:

using System;
using System.IO;
using System.Net.Sockets;
using System.Text;

namespace ModbusJsonTest
{
    class Program
    {
        static void Main(string[] args)
        {
            const int PORT_NO = 30001;
            const string SERVER_IP = "192.168.1.1";
            TcpClient client = new TcpClient(SERVER_IP, PORT_NO);
            StreamReader sr = new StreamReader(client.GetStream());
            StreamWriter sw = new StreamWriter((client.GetStream()));

        StringBuilder request = new();
        request.Append("{");
        request.Append("\"funcCode\":3,");
        request.Append("\"slaveId\":31,");
        request.Append("\"address\":0,");
        request.Append("\"quantity\":2,");
        request.Append("\"interval\":0");
        request.Append("}");

        Console.WriteLine(request.ToString());

        sw.WriteLine(request.ToString());
        sw.Flush();

        string data = sr.ReadLine();
        while(data!=null)
        {
            Console.WriteLine(data);
            data = sr.ReadLine();
        }
        client.Close();
    }
}

}

以上代码发送以下请求:

{"funcCode":3,"slaveId":31,"address":0,"quantity":2,"interval":0}

期待得到以下回复:

[{"slaveId":31,"funcCode":3,"address":0,"quantity":2,"data":[4,0,0,0,235]}]

如您所见,它在使用 Hercules 时有效:

我检查了我的代码是否能够正确地将请求发送到设备,似乎可以正常工作, 我使用 Hercules 作为服务器捕获了此消息(将设备设置为服务器)

我不知道我做错了什么,有什么有用的代码示例可以试试吗?

已编辑:代码卡在字符串 data = sr.ReadLine();代码确实 不继续执行通过这个...

【问题讨论】:

  • 您是否尝试过使用 Hercules 发送预期的回复?
  • 可能是您的服务器没有响应docs.microsoft.com/en-us/dotnet/api/… 的注释中描述的行尾字符。具体来说,在预期响应的末尾没有 \r\n\r\n,因此 sr.ReadLine() 既不会到达行尾,也不会到达流尾。
  • 另外,请尝试使用 Read 而不是 ReadLine

标签: c# tcpclient


【解决方案1】:

我可以在这里找到这篇文章:

Server Client send/receive simple text

那里描述的代码解决了这个问题,我猜 StreamReader 不是 此类工作的正确工具...

【讨论】:

    【解决方案2】:

    您的问题是 sr.ReadToEnd() 永远不会完成,因为流没有结束(而且,它永远不会结束 - 它是服务器和客户端之间的连续流)。

    相反,您需要使用缓冲区读取回复,或者假设响应以换行符终止并一次读取一行。

    例如,如果下面的代码以换行符结束,则将读取一行文本

    sw.WriteLine(request.ToString());
    sw.Flush();
    
    // Read in a single line of the reply.
    string line;
    while(!string.IsNullOrEmpty(line = sr.ReadLine())) 
    {
        Console.WriteLine(line);
    }
    

    您还可以使用one of the overloads of Stream.Read 读取字节数组。

    【讨论】:

    • 嗨,这不起作用,我在“line.Dump();”上放了一个断点但是代码永远不会到达它,代码被卡在“line = sr.ReadLine()”上,这意味着什么?
    • 这意味着您的 TCP 服务器没有用换行符终止响应。您将需要使用其中一种字节重载并手动读取字符串。很抱歉留下line.Dump() - 这是一个 Linqpad 扩展,不会编译....我会修复它。我也在为你处理一个字节样本。
    猜你喜欢
    • 2018-11-30
    • 2022-06-17
    • 1970-01-01
    • 2015-05-12
    • 2020-09-13
    • 2016-04-15
    • 2017-12-20
    • 1970-01-01
    • 2023-03-11
    相关资源
    最近更新 更多