TCPClient неправильно читает данные

Я разработал проект, который считывает данные с весов. Я могу читать данные, которые мне присылают весы; однако полученные наборы данных неудобны. Торговая марка весов - Desis.

Пример вывода ниже.

Output:

T,GS   17.27 g
ST,GS   17.27 g
T,GS   17.27 g
T,GS   17.27 g
27 g
ST,GS   17.27 g
ST,GS   17.27 g
ST,GS   17.27 g
ST,GS   17.27 g
ST,GS   17.27 g
ST,GS   17.27 g
30.89 g

ST,GS   17.27 g
ST,GS   17.27 g
ST,GS   17.27 g
ST,GS   17.27 g

Полученные данные должны быть ST, GS 17,27 г непрерывно.

Мои письменные коды:

public void Connect()
{
            m_tcpClient = new TcpClient();

            m_tcpClient.Connect(m_hostAdress, m_port);

}

public string ReadWithNewLine()
{

            this.Connect();
            m_netWorkStream = m_tcpClient.GetStream();
            m_streamReader = new StreamReader(m_netWorkStream);

            if (m_streamReader != null)
            {
                try
                {
                    m_readText = m_streamReader.ReadLine().TrimEnd();

                }
                catch (Exception ex)
                {

                }
            }
            return m_readText + "\r\n";
}

Есть ли ошибка в коде?


person mrtkprc    schedule 13.02.2016    source источник
comment
Что-то может пойти не так с ReadLine, но вы не узнаете об этом, потому что скрываете ошибки пустым блоком catch.   -  person Andrew Morton    schedule 13.02.2016
comment
Как вы вызываете ReadWithNewLine?   -  person rene    schedule 13.02.2016


Ответы (3)


Я не думаю, что в вашем коде есть какая-то ошибка. Но я думаю, что вы читаете по одной строке за раз. если вы хотите прочитать все строки один раз, вы можете использовать

 m_readText = m_streamReader.ReadToEnd().TrimEnd();

но если вы хотите читать построчно и получать данные, как вы задали вопрос, я думаю, что отправитель отправляет данные в этой последовательности.

person Muhammad USman    schedule 13.02.2016
comment
Я использую класс Thread.Timer, и мне нужно читать построчно, я хочу видеть вывод Hyperterminal. В Гипертерминале я вижу данные построчно. Как я могу сделать? - person mrtkprc; 13.02.2016

Вы заново создаете TcpClient при каждом вызове в ReadWithNewLine. Если вы сделаете это, TcpServer на другом конце должен закрыть старое соединение и запустить новое, согласовывая соединение, которое каждый раз будет терять пару байтов.

Оставаясь как можно ближе к вашему текущему дизайну, я предлагаю вам попробовать настройку со следующими изменениями:

    public void Connect()
    {
        if (m_tcpClient == null)
        {
            m_tcpClient = new TcpClient();
            m_tcpClient.Connect(m_hostAdress, m_port);
            m_netWorkStream = m_tcpClient.GetStream();
            m_streamReader = new StreamReader(m_netWorkStream);
        }
    }

    public string ReadWithNewLine()
    {

        this.Connect();

        try
        {
            m_readText = m_streamReader.ReadLine().TrimEnd();
        } 
        catch (Exception allExceptions)
        {
            m_readText = "Exception:" + allExceptions.Message;
            if (m_tcpClient!=null)
            {
                m_tcpClient.Close();
                m_tcpClient = null; // reset connection
            }
        }
        return m_readText + "\r\n";
    }

Обратите внимание, как я проверяю в методе Connect, что экземпляр TcpClient уже существует. Если нет, я создаю его и устанавливаю поток и ридер.

При первом вызове ReadWithNewLine он вызывает Connect и устанавливает соединение с вашими весами. При следующем вызове Connect ничего не сделает и повторно использует существующий считыватель для получения байтов.

Я также немного изменил вашу обработку исключений. Меньшее, что я мог сделать, это предложить некоторую обратную связь и сбросить настройки TcpClient. Возможно, вы захотите улучшить это, чтобы перехватывать только определенные исключения, которые там возникают.

person rene    schedule 13.02.2016

Существует множество методов, которые вы можете использовать для получения данных ответа от TCPClient. Я использовал потоковый код для форматирования вывода.

        private int TCPTimeOut = 10000;
        private int NetStreamTimeOut = 10000;
        private string ipAddress = "";
        private int port;
        private int intThreadSleep;
        private bool disposed = false;
        private TcpClient tcpClient = new TcpClient();

        private void GetTCPData()
        {
            tcpClient.Connect(ipAddress, port);
            tcpClient.ReceiveTimeout = TCPTimeOut;
            NetworkStream stream = tcpClient.GetStream();
            stream.ReadTimeout = NetStreamTimeOut;

            Byte[] data = new Byte[5210];
            string responseData = String.Empty;

            while (true)
            {
                Int32 bytes = stream.Read(data, 0, data.Length);
                System.Threading.Thread.Sleep(intThreadSleep);
                responseData = responseData + System.Text.Encoding.ASCII.GetString(data, 0, bytes);

                if (bytes > 10)
                {
                    var table = responseData.Split(new string[] { "\r\n", "\r", "\n" },
                                                 StringSplitOptions.None);

                    if (table.Count() > 3)
                    {
                        string line1 = table[0];
                        string line2 = table[1];
                        string line3 = table[2];
                        string line4 = table[3];
                        string line5 = table[4];
                        string line6 = table[5];

                        // SaveData(ipAddress, line1, line2, line3, line4, line5, line6);
                    }
                }
                responseData = String.Empty;
            }

            if (tcpClient != null)
            {
                tcpClient.GetStream().Close();
                tcpClient.Close();
            }

        }
person Abhilash Thomas    schedule 16.02.2016