Link to home
Start Free TrialLog in
Avatar of the_b1ackfox
the_b1ackfoxFlag for United States of America

asked on

C# Socket blocking problem

All, I have been trying to cobble together a working version of a program that receives messages from a host and send a response back.  There is an example message in one of the methods.  Line 197's intent is to send a response back to the sender notifying the sender that I have accepted their message (without this response their system will keep trying to send and resend the message)

I have been getting a blocking error from the senders side, and this :

Unable to read data from the transport connection: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.   (also from the senders side)

Can someone steer me in the right direction as to what I am doing wrong or how to fix this?


Here is the code:

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Net.Sockets;
using System.Net;


namespace HL7ReceiverTest
{
    public partial class Form1 : Form
    {
        List<String> TestMsg;
        public Form1()
        {
            InitializeComponent();
            SetTestVariables();
        }

        private void SetTestVariables()
        {
            TestMsg = new List<String>();
            TestMsg.Add(@"MSH|^~\&|Some dumb RIS|Some dumb location|Some Dumb PACS||20200402144906||ORM^O01|2004021449067041|P|2.3.1");
            TestMsg.Add(@"PID | 1 | 189.60787 | 280384 | 999 - 99 - 9999 | OGRE ^ FIONA ^ HAGATHA || 19740119 | F ||| PO BOX 001 ^ STE 233 ^ City ^ State ^ 12345 ^ US || (501)555 - 1212 ^^ (501)555 - 9876 | (501)581 - 3493 ||||| 999 - 99 - 9999");
        }


        static private List<String> CreateAck(List <String> DataList)
        {
            List<String> Results = new List<string>();
            foreach (String St in DataList)
            {
                if (St.Contains("MSH"))
                {
                    String[] DBts = St.Split('|');
                    Results.Add(DBts[0] + "|" + DBts[1] + "|" + DBts[4] + "||" + DBts[2] + "|" + DBts[3] + "|" + DBts[6] + "||ACK^O01|" + DBts[9] + "|" + DBts[10] + "|" + DBts[11]);
                    Results.Add("MSA|AA|" + DBts[9]);
                }
            }
            return (Results);
        }
        static private List<String> CreateAck(String Data)
        {
            List<String> Results = new List<string>();
            int Pt0 = -1;
            int Pt1 = -1;
            Pt0 = Data.IndexOf("PID|");
            Pt1 = Data.IndexOf("MSH|");
            if(Pt0>Pt1 && Pt1>=0)
            {
                String TData = Data.Substring(Pt1, Pt0);
                String[] DBts = TData.Split('|');
                Results.Add(DBts[0] + "|" + DBts[1] + "|" + DBts[4] + "||" + DBts[2] + "|" + DBts[3] + "|" + DBts[6] + "||ACK^O01|" + DBts[9] + "|" + DBts[10] + "|" + DBts[11]);
                Results.Add("MSA|AA|" + DBts[9]);
            }

            return (Results);
        }

        static private int GetDateKey()
        {
            int Results = -1;
            String TmpResult = DateTime.Now.ToString("yyyyMMdd");
            Results = Convert.ToInt32(TmpResult);
            return (Results);
        }

        private int GetDateKey(DateTime Data)
        {
            int Results = -1;
            String TmpResult = Data.ToString("YYYYMMDD");
            Results = Convert.ToInt32(TmpResult);
            return (Results);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            StartListening();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }



        public class StateObject
        {
            // Client  socket.  
            public Socket workSocket = null;
            // Size of receive buffer.  
            public const int BufferSize = 4098;
            // Receive buffer.  
            public byte[] buffer = new byte[BufferSize];
            // Received data string.  
            public StringBuilder sb = new StringBuilder();
        }

        public static ManualResetEvent allDone = new ManualResetEvent(false);

        public static void StartListening()
        {
            // Establish the local endpoint for the socket.  
            // The DNS name of the computer  
            // running the listener is "host.contoso.com".  
            IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
            IPAddress ipAddress = ipHostInfo.AddressList[3];
            IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);

            // Create a TCP/IP socket.  
            Socket listener = new Socket(ipAddress.AddressFamily,
                SocketType.Stream, ProtocolType.Tcp);

            // Bind the socket to the local endpoint and listen for incoming connections.  
            try
            {
                listener.Bind(localEndPoint);
                listener.Listen(100);

                while (true)
                {
                    // Set the event to nonsignaled state.  
                    allDone.Reset();

                    // Start an asynchronous socket to listen for connections.  
                    Console.WriteLine("Waiting for a connection...");
                    listener.BeginAccept(
                        new AsyncCallback(AcceptCallback),
                        listener);

                    // Wait until a connection is made before continuing.  
                    allDone.WaitOne();
                }

            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
            Console.WriteLine("\nPress ENTER to continue...");
            Console.Read();

        }

        public static void AcceptCallback(IAsyncResult ar)
        {
            // Signal the main thread to continue.  
            allDone.Set();

            // Get the socket that handles the client request.  
            Socket listener = (Socket)ar.AsyncState;
            Socket handler = listener.EndAccept(ar);

            // Create the state object.  
            StateObject state = new StateObject();
            state.workSocket = handler;
            handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                new AsyncCallback(ReadCallback), state);
        }

        public static void ReadCallback(IAsyncResult ar)
        {
            List<String> Notes = new List<string>();
            String content = String.Empty;

            // Retrieve the state object and the handler socket  
            // from the asynchronous state object.  
            StateObject state = (StateObject)ar.AsyncState;
            Socket handler = state.workSocket;
            EndPoint EP = handler.RemoteEndPoint;
            String IPA = EP.ToString();
            String ClientAddress = IPA.Substring(0, IPA.IndexOf(':') );
            // Read data from the client socket.
            int bytesRead = handler.EndReceive(ar);

            if (bytesRead > 0)
            {
                // There  might be more data, so store the data received so far.  
                state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
                content = state.sb.ToString();
                Notes.Add(content);
                handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                new AsyncCallback(ReadCallback), state);
            }
            if(bytesRead==0)
            {
                String HL7Response = "";
                String TData = state.sb.ToString();
                List <String> HL7Lines = CreateAck(TData);
                int DKey = GetDateKey();
                foreach(String Line in HL7Lines)
                {
                    HL7Response += Line;
                }
                Send(handler, HL7Response);
            }

           
        }

        private static void Send(Socket handler, String data)
        {
            // Convert the string data to byte data using ASCII encoding.  
            byte[] byteData = Encoding.ASCII.GetBytes(data);

            // Begin sending the data to the remote device.  
            handler.BeginSend(byteData, 0, byteData.Length, 0,
                new AsyncCallback(SendCallback), handler);
        }

        private static void SendCallback(IAsyncResult ar)
        {
            try
            {
                // Retrieve the socket from the state object.  
                Socket handler = (Socket)ar.AsyncState;

                // Complete sending the data to the remote device.  
                int bytesSent = handler.EndSend(ar);
                Console.WriteLine("Sent {0} bytes to client.", bytesSent);

                handler.Shutdown(SocketShutdown.Both);
                handler.Close();

            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }
       
        private void Document(String SenderIP, String HL7)
        {

        }
    }
 }
Avatar of Lukasz Zielinski
Lukasz Zielinski
Flag of Poland image

I guess sender is some 3rd party software, is that right?
Also can you confirm that you receive any data from sender?
Plus check the obvious: ip and port not blocked by firewall
Avatar of the_b1ackfox

ASKER

Yes, sender is 3rd party software.   I have confirmed I have received the message.  And there is no firewall blocking the path/ports
ASKER CERTIFIED SOLUTION
Avatar of Lukasz Zielinski
Lukasz Zielinski
Flag of Poland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Very nice response Lukasz.  I appreciate that you gave me a break down of what was going on.  The box is a little more illuminated!  ;)

Fox
glad I could help:)