skip to Main Content

I am very new in Socket Programming.
I am using the following code to receive incoming data from a pathology machine.

 byte[] buffer = new byte[2048];

        IPAddress ipAddress = IPAddress.Parse(SERVER_IP);
        IPEndPoint localEndpoint = new IPEndPoint(ipAddress, PORT_NO);

        Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        try
        {
            sock.Connect(localEndpoint);
        }
        catch (Exception ex)
        {
            throw ex;
        }

        while (true)
        {                
            int bytesRec = sock.Receive(buffer);
            data += Encoding.ASCII.GetString(buffer, 0, bytesRec);
            if (data.IndexOf("<EOF>") > -1)
            {
                break;
            }
        }

Issue I am facing…

  1. Machine is sending huge amount of data and gets busy and disconnects from program after some time.
  2. How can I start receiving data again? Is there any receiving event which fires automatically for incoming data?

2

Answers


  1. There is no generic way on how systems exchange data.
    Instead, there are different protocols for different kinds of applications or use cases, i.e. thinks like HTTP (web), TLS (transport encryption), SMTP (mail), ….
    You need to adhere to the protocol expected by the peer both for requesting data, transporting data, reconnecting, …
    It is unknown what protocol this is in your specific case, so one cannot recommend you a specific approach. Check documentation, vendor support etc. for the protocol documentation you need.

    If you are dealing with TCP/IP communication, using a NetworkStream (as commented) along with a StreamReader can simplify the process of reading incoming data.
    That would abstract away some of the lower-level byte handling (and the code is simpler).

    using System;
    using System.IO;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;
    
    IPAddress ipAddress = IPAddress.Parse(SERVER_IP);
    IPEndPoint localEndpoint = new IPEndPoint(ipAddress, PORT_NO);
    
    using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
    {
        try
        {
            socket.Connect(localEndpoint);
    
            using (NetworkStream networkStream = new NetworkStream(socket))
            using (StreamReader streamReader = new StreamReader(networkStream, Encoding.ASCII))
            {
                string message = string.Empty;
                while (!message.EndsWith("<EOF>"))
                {
                    message += streamReader.ReadLine(); // Assuming each message ends with a newline
                }
                // Process the received message
            }
        }
        catch (Exception ex)
        {
            // Handle exceptions
        }
    }
    

    The "Process the received message" part means understanding the protocol used by your pathology machine. If the machine uses a standard protocol (HTTP, TLS, SMTP, etc.), you should use a library or framework that supports that protocol out of the box. That way, you will be able to handle messages according to the protocol’s specifications, including reconnections and data transmission.

    For protocols that do not support signaling for "send next message," you might indeed need to close and reopen the connection. But this should be considered a last resort, as it is not efficient and might not be supported by all devices.


    As commented, considering asynchronous communication (e.g., using BeginReceive and EndReceive or async/await with NetworkStream) to improve performance and responsiveness, especially if you are dealing with large volumes of data.
    See also "Using Asynchronous Methods in ASP.NET 4.5"

    using System;
    using System.IO;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;
    using System.Threading.Tasks;
    
    async Task ReceiveDataAsync(string serverIp, int portNo)
    {
        IPAddress ipAddress = IPAddress.Parse(serverIp);
        IPEndPoint localEndpoint = new IPEndPoint(ipAddress, portNo);
    
        using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
        {
            await socket.ConnectAsync(localEndpoint);
    
            using (NetworkStream networkStream = new NetworkStream(socket))
            using (StreamReader streamReader = new StreamReader(networkStream, Encoding.ASCII))
            {
                StringBuilder completeMessage = new StringBuilder();
                char[] buffer = new char[2048];
                int bytesRead;
    
                while (true)
                {
                    bytesRead = await streamReader.ReadAsync(buffer, 0, buffer.Length);
                    completeMessage.Append(buffer, 0, bytesRead);
                    string message = completeMessage.ToString();
                    if (message.IndexOf("<EOF>") > -1)
                    {
                        // Process the message up to <EOF>
                        break;
                    }
                }
    
                // Process the received message
                Console.WriteLine("Received message: " + completeMessage.ToString());
            }
        }
    }
    
    Login or Signup to reply.
  2. There’s something wrong with your "pattern". The usual pattern is to "send a request"; and then "read the response". You should be identifying the actual machine you’re working with since it will document what "protocols" it actually supports; AND the amount of data it will return in response to a given request; so you have an idea of what you’re dealing with.

    The cases where a device just "transmits" without actually being asked to, are very few.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search