简体   繁体   English

如何在ssh连接中在.NET中实现发送和接收hl7数据

[英]How to implement send and receive hl7 data in .NET in ssh connection

I'm implementing an application in .Net. 我正在.Net中实现一个应用程序。 I have to create a connection by SSH which is works, but the HL7 data receiving fails. 我必须通过SSH创建有效的连接,但是HL7数据接收失败。 The destination is a raspberry pi. 目的地是树莓派。 So when I'm debugging the ssh client is connected, the port is forwarded, the tcp client also connected, but there is no answer for my queries. 因此,当我调试ssh客户端已连接时,端口已转发,tcp客户端也已连接,但是我的查询没有任何答案。 Plese suggest me some examples! 请给我一些例子!

In this project I have already implemented it on Android - it works fine. 在这个项目中,我已经在Android上实现了它-工作正常。 So in .Net I tried the NHapiTools library and I also tried the direct TcpClient way too. 因此,在.Net中,我尝试了NHapiTools库,也尝试了直接的TcpClient方法。 localPort = remotePort. localPort = remotePort。 I used localIP = "localhost" 我用localIP =“ localhost”

static void Main(string[] args)
    {
        try
        {
            PrivateKeyFile file = new PrivateKeyFile(@"./key/private.key");
        using (var client = new SshClient(remoteIP, sshPort, username, file))
            {
                client.Connect();
                var ci = client.ConnectionInfo;
                var port = new ForwardedPortLocal(localIP, localPort, client.ConnectionInfo.Host, remotePort);
                client.AddForwardedPort(port);
                port.Start();
                var req = "MSH|^~\\&|TestAppName||AVR||20181107201939.357+0000||QRY^R02^QRY_R02|923456|P|2.5";

                ////TCP
                var tcpClient = new TcpClient();
                tcpClient.Connect(localIP, (int)localPort);
                Byte[] data = System.Text.Encoding.ASCII.GetBytes(req);

                using (var stream = tcpClient.GetStream())
                {
                    stream.Write(data, 0, data.Length);

                    using (var buffer = new MemoryStream())
                    {
                        byte[] chunk = new byte[4096];
                        int bytesRead;

                        while ((bytesRead = stream.Read(chunk, 0, chunk.Length)) > 0)
                        {
                            buffer.Write(chunk, 0, bytesRead);
                        }

                        data = buffer.ToArray();
                    }
                }
   //I used this also with same result -> no respond
   //SimpleMLLP
   /*
   var connection = new SimpleMLLPClient(localIP, localPort, 
   Encoding.UTF8);
   var response = connection.SendHL7Message(req);
   */
            }
        }

        catch (Exception ex)
        {
            Console.WriteLine(ex);
        }
        Console.ReadLine();
    }

} }

So I experinced that the buffer size is 0 in TCP (due to time out). 因此,我体验了TCP中的缓冲区大小为0(由于超时)。 In the SimpleMLLP test SendHK7Message method never returns 在SimpleMLLP测试中,SendHK7Message方法永远不会返回

You are not implementing MLLP (also called LLP) protocol while sending message. 您在发送消息时未实现MLLP (也称为LLP)协议。

Description                 HEX     ASCII   Symbol
Message starting character  0B      11      <VT>
Message ending characters   1C,0D   28,13   <FS>,<CR>

This way, when you send a message to Listener (TCP/MLLP server), it looks for Start Block in your incoming data. 这样,当您将消息发送到侦听器(TCP / MLLP服务器)时,它将在传入数据中查找启动块。 It never finds it. 它永远找不到。 It just discards your entire message considering garbage. 考虑到垃圾,它只是丢弃您的整个消息。 Hence, you get nothing back from Listener. 因此,您没有从监听器中得到任何回报。

With MLLP implemented, your message (the stuff you are writing on socket) should look something like below: 随着MLLP实现,你的消息(东西你写上插座)看起来应该象下面这样:

<VT>MSH|^~\\&|TestAppName||AVR||20181107201939.357+0000||QRY^R02^QRY_R02|923456|P|2.5<FS><CR>

Note the <VT> , <CR> and <FS> are place holders in above message. 请注意<VT><CR><FS>是以上消息中的占位符。

You may refer to this article for detailed information (Read step 4 and onward): 你可以参考这个文章的详细信息(读第4步以后):

 using System; using System.Net; using System.Net.Sockets; using System.Text; namespace SimpleMllpHl7ClientAdvanced { public class Program { private static char END_OF_BLOCK = '\'; private static char START_OF_BLOCK = '\'; private static char CARRIAGE_RETURN = (char)13; static void Main(string[] args) { TcpClient ourTcpClient = null; NetworkStream networkStream = null; var testHl7MessageToTransmit = new StringBuilder(); //a HL7 test message that is enveloped with MLLP as described in my article testHl7MessageToTransmit.Append(START_OF_BLOCK) .Append("MSH|^~\\\\&|AcmeHIS|StJohn|CATH|StJohn|20061019172719||ORM^O01|MSGID12349876|P|2.3") .Append(CARRIAGE_RETURN) .Append("PID|||20301||Durden^Tyler^^^Mr.||19700312|M|||88 Punchward Dr.^^Los Angeles^CA^11221^USA|||||||") .Append(CARRIAGE_RETURN) .Append("PV1||O|OP^^||||4652^Paulson^Robert|||OP|||||||||9|||||||||||||||||||||||||20061019172717|20061019172718") .Append(CARRIAGE_RETURN) .Append("ORC|NW|20061019172719") .Append(CARRIAGE_RETURN) .Append("OBR|1|20061019172719||76770^Ultrasound: retroperitoneal^C4|||12349876") .Append(CARRIAGE_RETURN) .Append(END_OF_BLOCK) .Append(CARRIAGE_RETURN); try { //initiate a TCP client connection to local loopback address at port 1080 ourTcpClient = new TcpClient(); ourTcpClient.Connect(new IPEndPoint(IPAddress.Loopback, 1080)); Console.WriteLine("Connected to server...."); //get the IO stream on this connection to write to networkStream = ourTcpClient.GetStream(); //use UTF-8 and either 8-bit encoding due to MLLP-related recommendations var sendMessageByteBuffer = Encoding.UTF8.GetBytes(testHl7MessageToTransmit.ToString()); if (networkStream.CanWrite) { //send a message through this connection using the IO stream networkStream.Write(sendMessageByteBuffer, 0, sendMessageByteBuffer.Length); Console.WriteLine("Data was sent data to server successfully...."); var receiveMessageByteBuffer = Encoding.UTF8.GetBytes(testHl7MessageToTransmit.ToString()); var bytesReceivedFromServer = networkStream.Read(receiveMessageByteBuffer, 0, receiveMessageByteBuffer.Length); // Our server for this example has been designed to echo back the message // keep reading from this stream until the message is echoed back while (bytesReceivedFromServer > 0) { if (networkStream.CanRead) { bytesReceivedFromServer = networkStream.Read(receiveMessageByteBuffer, 0, receiveMessageByteBuffer.Length); if (bytesReceivedFromServer == 0) { break; } } } var receivedMessage = Encoding.UTF8.GetString(receiveMessageByteBuffer); Console.WriteLine("Received message from server: {0}", receivedMessage); } Console.WriteLine("Press any key to exit..."); Console.ReadLine(); } catch (Exception ex) { //display any exceptions that occur to console Console.WriteLine(ex.Message); } finally { //close the IO strem and the TCP connection networkStream?.Close(); ourTcpClient?.Close(); } } } } 

You should modify your following line of code as below: 您应该按以下方式修改您的以下代码行:

var req = START_OF_BLOCK + "MSH|^~\\&|TestAppName||AVR||20181107201939.357+0000||QRY^R02^QRY_R02|923456|P|2.5" + END_OF_BLOCK + CARRIAGE_RETURN;

For more open source code, you may refer to this github project. 有关更多开放源代码,您可以参考 github项目。

After days of struggling I have solved the problem. 经过几天的努力,我解决了问题。 The main error was with the port forwarding. 主要错误在于端口转发。 I would reccomend to use SSH.Net by Renci (There was algorithm error with Tamir ssh). 我建议使用Renci的SSH.Net(Tamir ssh出现算法错误)。 After ssh connection created I used this to port forward: 创建ssh连接后,我用它来转发端口:

           var port = new ForwardedPortLocal(localIP, localPort, "localhost", remotePort);

Check your localIP with ipconfig /all in cmd. 使用cmd中的ipconfig / all检查您的localIP。 Or use 127.0.0.1 as a loopback IP. 或使用127.0.0.1作为回送IP。 SimpleMLLPClient did not worked for me so I used the direct tcp client query way. SimpleMLLPClient对我不起作用,因此我使用了直接tcp客户端查询方式。 Like this: 像这样:

            TcpClient ourTcpClient = new TcpClient();
            ourTcpClient.Connect(localIP, (int)localPort); 
            NetworkStream networkStream = ourTcpClient.GetStream();

            var sendMessageByteBuffer = Encoding.UTF8.GetBytes(testHl7MessageToTransmit.ToString());

            if (networkStream.CanWrite)
            {
                networkStream.Write(sendMessageByteBuffer, 0, sendMessageByteBuffer.Length);

                Console.WriteLine("Data was sent to server successfully....");
                byte[] receiveMessageByteBuffer = new byte[ourTcpClient.ReceiveBufferSize];
                var bytesReceivedFromServer = networkStream.Read(receiveMessageByteBuffer, 0, receiveMessageByteBuffer.Length);

                if (bytesReceivedFromServer > 0 && networkStream.CanRead)
                {
                    receivedMessage.Append(Encoding.UTF8.GetString(receiveMessageByteBuffer));
                }

                var message = receivedMessage.Replace("\0", string.Empty);
                Console.WriteLine("Received message from server: {0}", message);
            }

So it gave me instant answer with 0 bytes (not due timeout). 所以它给了我0字节的即时答复(没有超时)。 And here comes Amit Joshi help. 这是阿米特·乔希(Amit Joshi)的帮助。 I used a query what he suggested with START_OF_BLOCK, CARRIAGE_RETURN and END_OF_BLOCK and finally started to work. 我使用他对START_OF_BLOCK,CARRIAGE_RETURN和END_OF_BLOCK的建议进行查询,然后终于开始工作了。 Thank you Amit Joshi! 谢谢阿米特·乔希!

Additional info: In Android (java/Kotlin) jsch session setPortForwardingL works fine with three params: 附加信息:在Android(java / Kotlin)中,jsch会话setPortForwardingL在以下三个参数中可以正常工作:

        val session = jsch.getSession("user", sshIP, sshPort)
        session.setPassword("")
        jsch.addIdentity(privatekey.getAbsolutePath())
        // Avoid asking for key confirmation
        val prop = Properties()
        prop.setProperty("StrictHostKeyChecking", "no")
        session.setConfig(prop)
        session.connect(5000)
        session.setPortForwardingL(localForwardPort, "localhost", remotePort)

        val useTls = false
        val context = DefaultHapiContext()
        connection = context.newClient("localhost", localForwardPort, useTls)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM