C# asynchronous socket client

I am trying to understand and develop a client that can communicate with a hardware system over TCP/IP.  I found an article on a basic client here (http://www.java2s.com/Code/CSharp/Network/AsyncTcpClient.htm) and modified the code slightly to test with.  I can connect to the hardware and return a response to verify that it is communicating but when I send a command it does not respond and throws an ObjectDisposedException in ReceiveData block when the disconnect button is clicked.    I assume it is waiting for the hardware to return data but I'm not sure why it isn't receiving.   I am able to connect and send commands with a simple console app.
using System;
using System.Drawing;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Windows.Forms;
 
 
public class AsyncTcpClient : Form
{
    private TextBox newText;
    private TextBox conStatus;
    private ListBox results;
    private Socket client;
    private byte[] data = new byte[1024];
    private int size = 1024;
 
    public AsyncTcpClient()
    {
        Text = "Asynchronous TCP Client";
        Size = new Size(400, 380);
 
        Label label1 = new Label();
        label1.Parent = this;
        label1.Text = "Enter text string:";
        label1.AutoSize = true;
        label1.Location = new Point(10, 30);
 
        newText = new TextBox();
        newText.Parent = this;
        newText.Size = new Size(200, 2 * Font.Height);
        newText.Location = new Point(10, 55);
 
        results = new ListBox();
        results.Parent = this;
        results.Location = new Point(10, 85);
        results.Size = new Size(360, 18 * Font.Height);
 
        Label label2 = new Label();
        label2.Parent = this;
        label2.Text = "Connection Status:";
        label2.AutoSize = true;
        label2.Location = new Point(10, 330);
 
        conStatus = new TextBox();
        conStatus.Parent = this;
        conStatus.Text = "Disconnected";
        conStatus.Size = new Size(200, 2 * Font.Height);
        conStatus.Location = new Point(110, 325);
 
        Button sendit = new Button();
        sendit.Parent = this;
        sendit.Text = "Send";
        sendit.Location = new Point(220, 52);
        sendit.Size = new Size(5 * Font.Height, 2 * Font.Height);
        sendit.Click += new EventHandler(ButtonSendOnClick);
 
        Button connect = new Button();
        connect.Parent = this;
        connect.Text = "Connect";
        connect.Location = new Point(295, 20);
        connect.Size = new Size(6 * Font.Height, 2 * Font.Height);
        connect.Click += new EventHandler(ButtonConnectOnClick);
 
        Button discon = new Button();
        discon.Parent = this;
        discon.Text = "Disconnect";
        discon.Location = new Point(295, 52);
        discon.Size = new Size(6 * Font.Height, 2 * Font.Height);
        discon.Click += new EventHandler(ButtonDisconOnClick);
    }
 
    void ButtonConnectOnClick(object obj, EventArgs ea)
    {
        conStatus.Text = "Connecting...";
        Socket newsock = new Socket(AddressFamily.InterNetwork,
                              SocketType.Stream, ProtocolType.Tcp);
        IPEndPoint iep = new IPEndPoint(IPAddress.Parse("10.5.48.225"), 4000);
        newsock.BeginConnect(iep, new AsyncCallback(Connected), newsock);
    }
 
    void ButtonSendOnClick(object obj, EventArgs ea)
    {
        byte[] message = Encoding.ASCII.GetBytes(newText.Text);
        client.BeginSend(message, 0, message.Length, SocketFlags.None, new AsyncCallback(SendData), client);
        newText.Clear();
    }
 
    void ButtonDisconOnClick(object obj, EventArgs ea)
    {
        client.Close();
        conStatus.Text = "Disconnected";
    }
 
    void Connected(IAsyncResult iar)
    {
        client = (Socket)iar.AsyncState;
        try
        {
            this.BeginInvoke(
                (MethodInvoker)delegate()
                {
                    client.EndConnect(iar);
                    conStatus.Text = "Connected to: " + client.RemoteEndPoint.ToString();
                    client.BeginReceive(data, 0, size, SocketFlags.None,
                                  new AsyncCallback(ReceiveData), client);
                });
        }
        catch (SocketException)
        {
            conStatus.Text = "Error connecting";
        }
    }
 
    void ReceiveData(IAsyncResult iar)
    {
        this.BeginInvoke(
            (MethodInvoker)delegate()
            {
                Socket remote = (Socket)iar.AsyncState;
                int recv = remote.EndReceive(iar);
                string stringData = Encoding.ASCII.GetString(data, 0, recv);
                results.Items.Add(stringData);
            });
    }
 
    void SendData(IAsyncResult iar)
    {
        Socket remote = (Socket)iar.AsyncState;
        int sent = remote.EndSend(iar);
        remote.BeginReceive(data, 0, size, SocketFlags.None, new AsyncCallback(ReceiveData), remote);
    }
 
    public static void Main()
    {
        Application.Run(new AsyncTcpClient());
    }
}

Open in new window

dspradlingIT SupportAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Jens FiedererTest Developer/ValidatorCommented:
Not sure exactly what you are saying here, you are a bit indefinite with your "it" and "I".....if the client can send a message and receive a response from the hardware (obviously I have no access to your hardware!) it sounds like you are doing well.

"I can connect" = your client connects?
"return a response" = your hardware responds to your client?  did your client send a command yet?  to what is it responding?
"I send a command" = you click the send button?
"it does not respond" = ?
0
dspradlingIT SupportAuthor Commented:
The client can connect to the hardware and does receive a response from the hardware stating that it is connected.  I then attempt to send a command to the hardware and expect a response.  I can verify the hardware is working correctly because I can telnet into the hardware server and it behaves normally.  The client does not behave as expected when a command is sent via the TCP client.  The client stops responding when a command is sent.  I have also tried to use this client to connect to a SMTP server and it behaves in a similar manner, meaning I can connect and receive a 220 response from the mail server but when I send a HELO command the client becomes unresponsive.  No exception is thrown.

"I can connect" = your client connects? --yes it connects

"return a response" = your hardware responds to your client? -- yes it responds with 1Connected to Eagle Test System 10.5.48.225 upon connection  (the response is received in the client)

did your client send a command yet?   to what is it responding? --I type the command A in the textbox and click the Send button.  The response should be ACK-Print Complete Enabled as verified via telnet

"I send a command" = you click the send button? --yes

"it does not respond" = ? --No

You could try and reproduce the results I am seeing against a mail server or other telnet service.
0
dspradlingIT SupportAuthor Commented:
Added note.  I found this code on MSDN on an Asynchronous Client Socket Example.  This code hangs on the socket response as well.  I don't get it.  I don't understand what is going wrong here.

using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Text;
 
// 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
{
 
    // 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
        {
 
            int port = 25;
            IPHostEntry ipHostInfo = Dns.GetHostEntry("mail.watlow.com");
            IPAddress ipAddress = ipHostInfo.AddressList[0];
 
            //int port = 4000;
            //IPAddress ipAddress = IPAddress.Parse("10.5.48.225");
 
            IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);
 
            // Create a TCP/IP socket.
            Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
 
            // Connect to the remote endpoint.
            client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), client);
            connectDone.WaitOne();
 
            //Receive(client);
            //receiveDone.WaitOne();
            //Console.WriteLine("Response received : {0}", response);
 
            // Send test data to the remote device.
            Send(client, "HELO");
            sendDone.WaitOne();
 
            // Receive the response from the remote device.
            Receive(client);
            receiveDone.WaitOne();
 
            // Write the response to the console.
            Console.WriteLine("Response received : {0}", response);
 
            // Release the socket.
            Console.ReadLine();
            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);
            Console.WriteLine("Read data from the remote device.");
            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));
                Console.WriteLine(state.sb);
 
                // Get the rest of the data.
                client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
                Console.WriteLine("Code hangs here");
            }
            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;
    }
}

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C#

From novice to tech pro — start learning today.