1

我正在研究通过串行 com 端口发送 MICROS 8700 固定消息的 POS 和我们的 PMS 之间的接口。我的经验是 C#、MVC、AJAX、webapp 端和更现代的技术。我对所有的 COM 串行端口通信和 Micros 仿真非常迷茫,但我已经做了我能做的。

我创建了一个 C# windows 服务,它接收消息并(从我所看到的)返回一条消息。POS 软件通过串行 COM 端口发送其消息。我中间有第 3 方软件,可以将其转换为 TCP。(我可以看到数据从 POS 传递到第 3 方软件上的 POS。)

我的软件正在侦听特定的 TCP 端口。

它可以很好地接收字节流。

转换为 ASCII 字符串。

校验和基于响应字符串创建,但不包括 SOH,直到并包括 ETX 字符。关联

使用 ASCII 编码将响应转换为字节数组。

它回复说,我认为是正确的格式,但它没有被 POS 软件记录。

我正在研究我的校验和计算不正确的理论,但是在更改校验和的确定方式时我没有取得任何进展。

我以 SOH (\u0001) 字符开始每条消息,并以 EOT (\u0004) 结束。我还用 STX (\u0002) 和 ETX (\u0003) 分隔消息

我什至无法获得要记录的基本错误消息。

只是为了让我看起来并不懒惰/无能,我所要做的只是一个示例日志文件以及我可以在互联网上找到的内容。

我想我需要“1000/2000/4700/8700 pms 接口规范手册”,但我无法获得这份副本。

我的程序收到消息

1修订版 1 1 120 2001069B

这是

SOH 1Rev 1 STX 1 120 2001ETX069BEOT

我的程序回应

1Rev 1 1/无效条目 0AC5

这是

SOH 1Rev 1 STX 1/无效条目 ETX0AC5EOT

SOH 终端 ID STX 1/INVALID ENTRY ETXchecksumEOT

有时,当 POS 端的连接超时时,每隔 30 秒,回复的第一个字符就会出现在 POS 日志中,但我相信这与缓冲区有关。

也许我发送了一些非常错误的东西,而 POS 软件没有达到预期的效果,因此它没有记录/处理它。

我正在发送 EOT,我相信它会告诉 POS 消息已完成,并且 Windows 服务也会关闭流。所以我不认为 POS 正在等待消息的结束。

我读过一些可能有用的帖子 Link Link

真的,我想要一些关于如何生成校验和的建议,或者关于我的问题可能是什么的任何其他建议。请查看我尝试过的两个不同的校验和代码块。

链接 “校验和是 SOH 之后所有字符的 16 位二进制加法(不包括奇偶校验,如果适用),直到并包括 ETX 字符。校验和最初设置为零。对于传输,校验和表示为四个 ASCII 十六进制字符。”

        private static string GetChecksum(string s)
    {
        int checksum = 0;

        byte[] binary = Encoding.ASCII.GetBytes(s);

        foreach (byte b in binary)
        {
            checksum = ((checksum + b) & 0xFF);
        }
        checksum = (((checksum ^ 0xFF) + 1) & 0xFF);
        return checksum.ToString("X4");
    }

 private static string GetChecksum(string data)
    {
        short checksum = 0;
        int byteCount = data.Length;
        int index = 0;
        char current;
        byte intOffset = 48;
        byte alphaOffset = 55;
        byte scale = 16;

        if (byteCount < 2) // bad string
            return "Error";

        while (index < byteCount - 1)
        {
            current = data[index++];
            if (current < 'A')
            {
                checksum += (byte)(((byte)current - intOffset) * scale);
            }
            else
            {
                checksum += (byte)(((byte)current - alphaOffset) * 16);
            }
            current = data[index++];
            if (current < 'A')
            {
                checksum += (byte)(((byte)current - intOffset));
            }
            else
            {
                checksum += (byte)(((byte)current - alphaOffset));
            }
            index++;
        }
        return checksum.ToString("X4");
    }
4

1 回答 1

2

事实证明,在我回复我的消息之前,我需要回复一个 ACK​​。

十进制八进制十六进制二进制字符

006 006 0x06 00000110 ACK(确认)

或者对于 C#

static char ACK = '\u0006';


byte[] ackMsg = System.Text.Encoding.ASCII.GetBytes(ACK.ToString());
                            stream.Write(ackMsg, 0, ackMsg.Length);

并且还具有如下计算的校验和

现在我的回答已通过软件验证和显示。

“ASCII 字符,表示校验和。总是有 4 个数字。它们是 HEX(0 到 9 由十六进制 0x30 .. 0x39 表示,AF 由十六进制 0x41 到 0x46 表示)。校验和通过最初设置为 0 来计算"

 private static string GetChecksum(string s)
        {//this gives matching checksums
            int checksum = 0;

            byte[] binary = Encoding.ASCII.GetBytes(s);

            foreach (byte b in binary)
            {
                checksum = ((checksum + b));
            }
            return checksum.ToString("X4");
        }

我希望这可以帮助任何被困在旧技术上的人。

于 2018-11-12T12:44:10.613 回答