We help IT Professionals succeed at work.

C# Socket blocking problem

the_b1ackfox
the_b1ackfox asked
on
60 Views
Last Modified: 2020-05-04
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)
        {

        }
    }
 }
Comment
Watch Question

Lukasz Zielinskisoftware developer
CERTIFIED EXPERT
Top Expert 2008

Commented:
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
the_b1ackfoxTechnophile

Author

Commented:
Yes, sender is 3rd party software.   I have confirmed I have received the message.  And there is no firewall blocking the path/ports
software developer
CERTIFIED EXPERT
Top Expert 2008
Commented:
This one is on us!
(Get your first solution completely free - no credit card required)
UNLOCK SOLUTION
the_b1ackfoxTechnophile

Author

Commented:
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
Lukasz Zielinskisoftware developer
CERTIFIED EXPERT
Top Expert 2008

Commented:
glad I could help:)

Gain unlimited access to on-demand training courses with an Experts Exchange subscription.

Get Access
Why Experts Exchange?

Experts Exchange always has the answer, or at the least points me in the correct direction! It is like having another employee that is extremely experienced.

Jim Murphy
Programmer at Smart IT Solutions

When asked, what has been your best career decision?

Deciding to stick with EE.

Mohamed Asif
Technical Department Head

Being involved with EE helped me to grow personally and professionally.

Carl Webster
CTP, Sr Infrastructure Consultant
Empower Your Career
Did You Know?

We've partnered with two important charities to provide clean water and computer science education to those who need it most. READ MORE

Ask ANY Question

Connect with Certified Experts to gain insight and support on specific technology challenges including:

  • Troubleshooting
  • Research
  • Professional Opinions
Unlock the solution to this question.
Join our community and discover your potential

Experts Exchange is the only place where you can interact directly with leading experts in the technology field. Become a member today and access the collective knowledge of thousands of technology experts.

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.