Resolved Socket Programming

tdignan87

Well-known member
Joined
Jul 8, 2019
Messages
95
Programming Experience
Beginner
Hi
I am currently using socket programming to send commands to a device and it sends reply commands.
How can i get the console to read the reply thats returned?

So far i have

C#:
 m_socClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                System.Net.IPAddress remoteIPAddress = System.Net.IPAddress.Parse(DatalogicIP);
                System.Net.IPEndPoint remoteEndPoint = new System.Net.IPEndPoint(remoteIPAddress, DatalogicPort);
                m_socClient.Connect(remoteEndPoint);
                Console.WriteLine("Connection Successful");
                Console.ReadLine();

able to connect successfully and then im sending

C#:
string hostMode = "<ESC>[C";
C#:
 byte[] byData = System.Text.Encoding.ASCII.GetBytes(hostMode);
                m_socClient.Send(byData);

I should be receiving <ESC> H <CR><LF> back but how do i get console to listen, and show replies
Once i have the H back i want to be able to send another command after that

Appreciate any help (new to socketing)

Thanks
Tom
 
Hi Sheepings,
Yeah it did - Do you know whats the best way for verifying the reply
Example IF my reply is <ESC>H<CR><LF> then ..

C#:
 // Receive the response from the remote device. 
                    int bytesRec = sender.Receive(bytes);
                    Console.WriteLine("{0}",
                        Encoding.ASCII.GetString(bytes, 0, bytesRec));

This returns the bytes OK but it would be good if i can verify if i get that response and if no response after say 10 seconds time out. What would be your best opinion for handling this? Cheers - Hope you had a good weekend.
 
It usually pays to read the documentation for the classes that you use. For example, just scanning the Socket class documentation, it shows that it has a ReceiveTimeout property that is described as:
Gets or sets a value that specifies the amount of time after which a synchronous Receive call will time out.
 
Hey,
I took the asynchorous example from Windows.
This is my Code
C#:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace SVS_Console
{
    // State object for receiving data from remote device. 
    public class StateObject
    {
        // Client socket. 
        public Socket workSocket = null;
        // Size of receive buffer. 
        public const int BufferSize = 256;
        // Receive buffer. 
        public byte[] buffer = new byte[BufferSize];
        // Received data string. 
        public StringBuilder sb = new StringBuilder();
    }

    public class AsynchronousClient
    {
        // The port number for the remote device. 
        private const int port = 1023;

        // ManualResetEvent instances signal completion. 
        private static ManualResetEvent connectDone =
            new ManualResetEvent(false);
        private static ManualResetEvent sendDone =
            new ManualResetEvent(false);
        private static ManualResetEvent receiveDone =
            new ManualResetEvent(false);

        // The response from the remote device. 
        private static String response = String.Empty;

        private static void StartClient()
        {
            // Connect to a remote device. 
            try
            {
                // Establish the remote endpoint for the socket. 
                // The name of the   
                // remote device is "host.contoso.com". 
                IPHostEntry ipHostInfo = Dns.GetHostEntry("192.168.4.15");
                IPAddress ipAddress = ipHostInfo.AddressList[0];
                IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);

                // Create a TCP/IP socket. 
                Socket client = new Socket(ipAddress.AddressFamily,
                    SocketType.Stream, ProtocolType.Tcp);
                Console.WriteLine("Connecting to Datalogic device " + ipAddress + "");
                // Connect to the remote endpoint. 
                client.BeginConnect(remoteEP,
                    new AsyncCallback(ConnectCallback), client);
                connectDone.WaitOne();

                Console.WriteLine("Press To Send Command For Host Mode Programming To The System");
                Console.ReadLine();
                // Send test data to the remote device. 
                Send(client, "\0C\r\n");
                sendDone.WaitOne();
                Console.WriteLine("Press to receive");
                // Receive the response from the remote device. 
                Receive(client);
                receiveDone.WaitOne();

                // Write the response to the console. 
                Console.WriteLine("Response received : {0}", response);


                Console.ReadLine();
                Console.WriteLine("Did you read Response?");


                // Release the socket. 
               // client.Shutdown(SocketShutdown.Both);
              //  client.Close();

            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }

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

                // Complete the connection. 
                client.EndConnect(ar);

                Console.WriteLine("Socket connected to {0}",
                    client.RemoteEndPoint.ToString());

                // Signal that the connection has been made. 
                connectDone.Set();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }

        private static void Receive(Socket client)
        {
            try
            {
                // Create the state object. 
                StateObject state = new StateObject();
                state.workSocket = client;

                // Begin receiving the data from the remote device. 
                client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                    new AsyncCallback(ReceiveCallback), state);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }

        private static void ReceiveCallback(IAsyncResult ar)
        {
            try
            {
                // Retrieve the state object and the client socket   
                // from the asynchronous state object. 
                StateObject state = (StateObject)ar.AsyncState;
                Socket client = state.workSocket;

                // Read data from the remote device. 
                int bytesRead = client.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));

                    // Get the rest of the data. 
                    client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                        new AsyncCallback(ReceiveCallback), state);
                }
                else
                {
                    // All the data has arrived; put it in response. 
                    if (state.sb.Length > 1)
                    {
                        response = state.sb.ToString();
                    }
                    // Signal that all bytes have been received. 
                    receiveDone.Set();
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }

        private static void Send(Socket client, 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. 
            client.BeginSend(byteData, 0, byteData.Length, 0,
                new AsyncCallback(SendCallback), client);
        }

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

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

                // Signal that all bytes have been sent. 
                sendDone.Set();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }

        public static int Main(String[] args)
        {
            StartClient();
            return 0;
        }
    }
}

I have put a ConsoleReadLine after receiving the response from the remote device.
C#:
Receive(client);
receiveDone.WaitOne();
                // Write the response to the console. 
                Console.WriteLine("Response received : {0}", response);

Nothing is coming back when i am replying in Hercules. I am sending this back for testing (below)

1583765585270.png


Basically once i send <ESC>C i will be receiving back <ESC>H<CR><LF>. Once i receive that i need to check, then send another command <ESC>B, and i then receive a <ESC>S<CR><LF> back. Once i have that, i then send another command then i need to read the strings coming back after that and count them if possible.

Cheers
 
Did you set a breakpoint on ReceiveCallback()? Is it even being called?
 
Inserted breakpoint and its behaving the same.Ah i figured this part would call the receive back from receive


sendDone.WaitOne();
Console.WriteLine("Press to receive");
// Receive the response from the remote device.
Receive(client);
receiveDone.WaitOne();
 
So is your breakpoint being hit?
 
Breakpoijt is turning red circle when enabling but not hitting (doing anything). Going to check if I have it in debug mode and check debug settings. The code looks ok so I cant srr why it's not showing the results... argh..
 
When you place the red dot on whatever line you want to step into the code -on-, this is only a break point, and upon that code ever being reached, your program will pause and your debugger will indicate with a yellow arrow mark; indicating that line has been reached by whatever calling code called it. And upon this step, you need to press F11 to step through the code! There is a debug tutorial in my signature, which you can avail and benefit from.

This example screenshot shows the break point placed but not reached.

Screenshot_83.jpg


This example screenshot shows the break point has been placed and also reached.

Screenshot_84.jpg
 
Last edited:
Step through the callback and see the values of the variables...
 
Sorry for my stupidity.
I cant see what its not getting my replies backk

If i comment out the below the code runs through, obviously no reply. If its in the program, it is waiting on the reply but not getting the replies back.
I've looked through the program again on microsoft and cannot see any glaring differences... argh

C#:
 // Receive the response from the remote device. 
                Receive(client);
                receiveDone.WaitOne();



                // Write the response to the console. 
                Console.WriteLine("Response received : {0}", response);



// Write the response to the console.
Console.WriteLine("Response received : {0}", response);


Something must be wrong at this part... but i cant figure out what

C#:
 private static void Receive(Socket client)
        {
            try
            {
                // Create the state object. 
                StateObject state = new StateObject();
                state.workSocket = client;

                // Begin receiving the data from the remote device. 
                client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                    new AsyncCallback(ReceiveCallback), state);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }

        private static void ReceiveCallback(IAsyncResult ar)
        
        {
            try
            {
              
                // Retrieve the state object and the client socket   
                // from the asynchronous state object. 
                StateObject state = (StateObject)ar.AsyncState;
                Socket client = state.workSocket;

                // Read data from the remote device. 
                int bytesRead = client.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));

                    // Get the rest of the data. 
                    client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                        new AsyncCallback(ReceiveCallback), state);
                }
                else
                {
                    // All the data has arrived; put it in response. 
                    if (state.sb.Length > 1)
                    {
                        response = state.sb.ToString();
                    }
                    // Signal that all bytes have been received. 
                    receiveDone.Set();
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }
 
I didn't link this in my signature for fun : Navigate code with the debugger - Visual Studio and then tell you to read it so you can identify what is going on in your project.

Just aside note :

C#:
.WaitOne();

According to the docs :
WaitOne()Blocks the current thread until the current WaitHandle receives a signal.
WaitHandle.WaitOne Method (System.Threading) - If cancelling out that line helps, then that means something is likely blocking your calling code. Only by debugging will you find what that is. Nobody but you can do that for you.

Something else is you shouldn't be writing your manual reset events with the hardcoded false boolean, but instead you would be recommended to use Get;Setters; instead. :
C#:
private static ManualResetEvent receiveDone = new ManualResetEvent(false);

Despite that Microsoft themselves actually provide the documentation as you have followed and not as I have recommended changing too may also cause you some issues. The idea of the ManualResetEvent is that you are in control of setting when and how the reset event is called. Also note the docs also say the following :
Pressing the Enter key again causes the example to call the Reset method and to start one more thread, which blocks when it calls WaitOne. Pressing the Enter key one final time calls Set to release the last thread, and the program ends.

See the docs regarding that quote : ManualResetEvent Class (System.Threading)

Lastly, read that debug link that I linked and then start stepping into your code, checking everything that currently executes. Note; if any of your calling code is told to keep polling up other methods while one executes, you will need to set a break point on those other methods too so the debugger can catch when they also fire... There are other issues I can see with the example you provided, but there is only so much advice I can give you, and all of which would be evident to you if you actually debugged your code.
 
Back
Top Bottom