Linda Motaung
Linda Motaung

Reputation: 9

TcpClient hangs after connection to remote host & application freezes c#

I am trying to establish a connection to a remote host via IP address and Port number. The connection does get established (even verified using cmd netstat) however when I try to close the connection in code:

clientConnection.Client.Close();
clientConnection.Client.Dispose();
clientConnection.Close();

The program crashes because the socket does not have any available data to be read from the client stream. In my windows application (client) I have a button which I click to call the ConnectToFalcon method and that calls the ReadStream method. Please let me know where have I been going wrong.

  public void readStream(object argument)
    {

            clientConnection = (TcpClient)argument;
            //TcpClient client = new TcpClient();

            DateTime start_time = DateTime.Now;
            TimeSpan delay = new TimeSpan(0, 0, 10);
            while (clientConnection.Available == 0)
            {
                Application.DoEvents();
                if (DateTime.Now.Subtract(start_time) > delay)
                    break;
            }


            if ((clientConnection != null) && (clientConnection.Available > 0))
            {
                var message = new byte[1];
                Array.Resize(ref message, clientConnection.Available);
                //remove below two lines and if-statement block if program crashes
                clientConnection.Client.ReceiveTimeout = 20000; //Timeout after 20 seconds
                clientConnection.SendTimeout = 20000;
                if (clientConnection.Client.ReceiveTimeout <= 20000 || clientConnection.SendTimeout == 20000)
                {
                    clientConnection.Client.Receive(message);
                    string testResult = System.Text.Encoding.Default.GetString(message);
                }
                else
                {
                    MessageBox.Show("Time expired before read operation completed.");
                }
            }
            else if (((clientConnection == null) && (clientConnection.Available <= 0)) || (clientConnection.Connected == false))
            {
                clientConnection.Close();
                MessageBox.Show("Closing client connection due to insufficient amount of data available to be read");
            }

            //clientConnection.Client.Close();
            //clientConnection.Client.Dispose();
            //clientConnection.Close();
        }}


  public void ConnectToFalcon(string IPaddress, int port)
    {

            clientConnection = new TcpClient();
            //var result = clientConnection.BeginConnect(IPaddress, port, new AsyncCallback(callback), clientConnection);
            var result = clientConnection.BeginConnect(IPaddress, port, null, null);
            var success = result.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(1));

            if (success == false)
            {
                MessageBox.Show("Failed to connect");
            }
            else
            {
                MessageBox.Show("Client connected...");
                while (true)
                {
                    Thread t = new Thread(readStream);
                    t.Start(clientConnection); //A new thread is spawned
                    //t.Start();
                }
            }       
    }

enter image description here

Upvotes: 0

Views: 813

Answers (1)

Linda Motaung
Linda Motaung

Reputation: 9

According to @Luaan, You must call EndConnect on the IAsyncResult in the callback function in order to acknowledge the client request.`

    public void callback(IAsyncResult ar)
    {
        this.clientConnection.EndConnect(ar);
    }

    var result = clientConnection.BeginConnect(ip, port, new AsyncCallback(callback), clientConnection);

Upvotes: 1

Related Questions