Преобразование кодировки TN5250 в C#

У меня есть подключение к IBM i (AS/400), которое обменивается данными по протоколу/кодированию под названием TN5250. Мне не удалось сопоставить его ни с одной из кодировок перечислено здесь; как я могу преобразовать этот текст во что-то, что я могу использовать? UTF8, ASCII; подойдет что угодно в удобном для Windows текстовом формате. Это не должно включать покупку сторонней библиотеки.

Вот некоторый «рабочий» код, который я нашел в другом месте. "адрес" - это IP-адрес.

        Socket SocketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        System.Net.IPEndPoint remoteEndPoint = new System.Net.IPEndPoint(IPAddress.Parse("address"), 23);
        SocketClient.Connect(remoteEndPoint);
        byte[] buffer = new byte[10];
        textBox1.Text += Receive(SocketClient, buffer, 0, buffer.Length, 10000).Trim() + "\r\n";
    }
    public static string Receive(Socket socket, byte[] buffer, int offset, int size, int timeout)
    {
        int startTickCount = Environment.TickCount;
        int received = 0;  // how many bytes is already received
        do
        {
            if (Environment.TickCount > startTickCount + timeout)
                throw new Exception("Timeout.");
            try
            {
                received += socket.Receive(buffer, offset + received, size - received, SocketFlags.None);
                return Encoding.GetEncoding(37).GetString(buffer, 0, buffer.Length);
                //byte[] buf = Encoding.Convert(Encoding.GetEncoding("iso-8859-1"), Encoding.UTF8, buffer);
                //return Encoding.GetEncoding("IBM500").GetString(buf, 0, buffer.Length);
            }
            catch (SocketException ex)
            {
                if (ex.SocketErrorCode == SocketError.WouldBlock ||
                    ex.SocketErrorCode == SocketError.IOPending ||
                    ex.SocketErrorCode == SocketError.NoBufferSpaceAvailable)
                {
                    // socket buffer is probably empty, wait and try again
                    Thread.Sleep(30);
                }
                else
                    throw ex;  // any serious error occurr
            }
        } while (received < size);
        return "";
    }

Это Telnet-соединение. Отлично работает в окне телнета Windows. Решение, которое мне действительно нужно, — это способ захвата stdout из сеанса telnet, но очевидно, что терминальные программы, такие как Telnet, не пишут в stdout.


person tsilb    schedule 05.07.2011    source источник


Ответы (3)


Проект TN5250J — это работающий клиент TN5250, написанный на Java.

TN5250 — это протокол IBM, работающий поверх Telnet. Он предназначен для семейства «тупых» терминалов с зеленым экраном IBM среднего уровня. Это семейство представляет собой блочный режим, то есть хост отправляет полную панель дисплея клиенту за одну передачу, а клиент отправляет полную панель дисплея обратно на хост за одну передачу. Это, в отличие от посимвольной передачи.

В качестве общего обзора протокол 5250 описывает, как форматировать дисплей (поле начала/конца, атрибуты поля, такие как подчеркивание и цвет), а также допустимые функциональные клавиши. Клиент должен понимать эти инструкции по форматированию, чтобы правильно отображать данные, поступающие от хоста. Точно так же клиент не отправляет обратно полную панель отображения, включая константы и форматирование; вместо этого он отправляет обратно поля с возможностью ввода.

Стандартного вывода как такового нет; удобочитаемая панель дисплея требует рендеринга клиентом. Вы можете получить хорошее представление о необработанных данных, используя Wireshark для захвата пакетов и сравнения их с фактическим дисплеем TN5250, показывающим ту же транзакцию.

person Buck Calabro    schedule 05.07.2011

Из этой статьи видно, что кодировка схема EBCDIC character-encoding scheme.

Дополнительные сведения см. в разделе Как преобразовать коды символов ASCII и EBCDIC. Это в VB, но вы должны быть в состоянии преобразовать его в C#. Также есть реализация на странице Джона Скита здесь

Как преобразовать EBCDIC в ASCII в C#. Судя по этому сообщению, вы можете использовать кодировку 37 IBM037 IBM EBCDIC (US-Canada) из предоставленного вами списка: Encoding ebcdic = Encoding.GetEncoding("IBM037");

person SwDevMan81    schedule 05.07.2011
comment
Нет, я пробовал все кодировки EBCDIC. Если мне не нужно преобразовать что-то еще между ними, чтобы получить обычный текст? - person tsilb; 06.07.2011

TN 5250 - это не кодировка. Это очень сложный протокол.

Спецификацию можно найти здесь: http://www.ietf.org/rfc/rfc1205.txt (Обратите внимание, что эта спецификация даже не полная)

Легкого преобразования не бывает. Вам нужно написать тысячи строк кода или использовать уже существующий проект, такой как, например, этот на C++ для Linux и Windows: http://sourceforge.net/projects/tn5250/files/

на С# ничего не нашел

person Elmue    schedule 30.07.2015