How do I debug this socket error?

I am developing an application that using a sockets to communicate with a measurement device.  It is communicating fine and returning data as I want.  However, when I sometimes click on the "Stop" button, I receive an IO exception that I have attached as a .JPG.  Some relevant pieces of code are attached as snippets.  Thank you and let me know if you need more information.


private void btnStopCalibration_Click(object sender, EventArgs e)
        {
            this.WorkerThreadAlive = false;
            this.ExposureWorkerThreadAlive = false;
            this.ElapsedTimeWorkerThreadAlive = false;
            try
            {
               // this.ElapsedTimeMonitorThread.Suspend();
              //  this.ExposureMonitorThread.Suspend();
                //this.EnvironmentalMonitorThread.Abort();
                this.EnvironmentalMonitorThread = null;
                this.btnStart.Enabled = true;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
         //  this.StopWorkerThread();
            this.tcp2701.disconnect();
 
       }
 
 
 
The following routine is what is started from a communications class I wrote.
 
 public string read()
        {
            string ival = "";
            ival = this.KI2701Read( ref ival);
            return ival;
        }
 
        public string KI2701Read(ref string KIdata)
        {
            //  Read network stream into byte buffer
 
            try
            {
                
                byte[] bytes = new byte[KI2701Client.ReceiveBufferSize];
KI2701Stream.Read(bytes,0,KI2701Client.ReceiveBufferSize);
                KIdata = System.Text.ASCIIEncoding.ASCII.GetString(bytes);
                if (KIdata != null)
                {
                    this.thevalue = KIdata.ToString();
                    return this.thevalue;
                }
                else
                {
                    return "-";
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
 
            return string.Empty;
 
            //  Debug.WriteLine(KIdata)
        }
 
        public void close()
        {
            this.close();
        }
 
    }

Open in new window

sshot-5.jpg
jvalescuAsked:
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.

gnoonCommented:
This's what I guess based on the error message

1) you perform read/write the device on multi-threads
2) when stop's pressed, you signal to the read-thread to stop reading, then you disconect

I think the problem is disconect operation has finished before the stop signal operation.
To prove this, just sleep() for awhile within brfore disconnect to make sure that the reading process has already finished.

  ...
  try{Thread.Sleep(100);}catch(Exception){}
  this.tcp2701.disconnect();
}
0
jvalescuAuthor Commented:
Thanks for the quick response.  I tried what you said, but got the first error posted, followed by a new one that I've attached.  I think you are on to something, however.

 
General.cs
===============
 
 public void send(string KIData)
        {
  THIS IS LINE 55 ===>     KI2701Stream = KI2701Client.GetStream();
            KIData = (KIData + "\r");
            //  Add control reset to the command line
            KIByte = System.Text.ASCIIEncoding.ASCII.GetBytes(KIData);
            //  Convert to byte
            KI2701Stream.Write(KIByte, 0, KIData.Length);
            //  Send data
        }
 
 public void KIInput(ref string KIstatus)
        {
            string myval = "";
 THIS IS LINE 226 ====>         send("SYST:FRSW?");
           // myval = KI2701Read(ref string KIData);
            myval = read();
            if ((KIData == "1"))
            {
                KIstatus = "Front";
            }
            else
            {
                KIstatus = "Rear";
            }
        }
 
 
 
 
frmVoltMeter.cs
================
 
try
  {
                    if (this.tcp2701 != null)
                    {
       THIS IS LINE 623 ===>      this.tcp2701.KIInput(ref tcp2701.KIstatus);
                        this.SetLabel(this.lblinput, tcp2701.KIstatus, Color.BurlyWood, true);
                        // this.SetLabel(this.lblValue, this.txtip.Text, Color.Black, true);
                        buffcounter++;
                        if (buffcounter == 1 && onetimeshot == true)
                        {
                            this.SetLabel(this.lblChamber1, this.txtip.Text.Substring(0, 8), Color.Black, true);
                            onetimeshot = false;
                        }
                        if (buffcounter >= 20)
                        {
                            this.SetLabel(this.lblChamber1, this.txtip.Text.Substring(0, 8), Color.Black, true);
                            buffcounter = 0;
                        }
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                }

Open in new window

sshot-6.jpg
0
gnoonCommented:
I dont see where you initiate KI2701Client.
0
Cloud Class® Course: MCSA MCSE Windows Server 2012

This course teaches how to install and configure Windows Server 2012 R2.  It is the first step on your path to becoming a Microsoft Certified Solutions Expert (MCSE).

gnoonCommented:
It's Null but you're trying to call GetStream() on it.
0
jvalescuAuthor Commented:
This is the entire General.cs class.  I added a null reference check in the send method to avoid the GetStream() call if KI2701 client is null, but I get the same above errors.
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
 
 
//using System.Text.Encoding;
 
namespace Keithley2701ClassLib
{
    //class General
    //{
    //}
 
    public class General
    {
 
        // 
        // Version 1.1
        // EEB
        // 
        public const Int16 port = 1394;
 
        public  System.Net.Sockets.TcpClient KI2701Client = new System.Net.Sockets.TcpClient();
        
 
        public  System.Net.Sockets.NetworkStream KI2701Stream;
 
        public  string KIstatus;
 
        public  bool connected = false;
 
        public string ip = "192.168.254.54";
 
       // public string port = "1394";
 
        public  byte[] KIByte;
 
        public  string KIData;
 
        public bool front = false;
 
        private bool dis = false;
 
        public string thevalue = "-";
 
        public bool configok = false;
 
 
 
 
 
        public void send(string KIData)
        {
            if (KI2701Client != null)
            {
                KI2701Stream = KI2701Client.GetStream();
                KIData = (KIData + "\r");
                //  Add control reset to the command line
                KIByte = System.Text.ASCIIEncoding.ASCII.GetBytes(KIData);
                //  Convert to byte
                KI2701Stream.Write(KIByte, 0, KIData.Length);
                //  Send data
            }
        }
 
        public void connect(string ip)
        {
            
            try
            {
                KI2701Client.Connect(ip, port);
                KI2701Stream = KI2701Client.GetStream();
                if ((KI2701Stream.CanWrite && KI2701Stream.CanRead))
                {
                    connected = true;
                }
                else
                {
                    connected = false;
                }
            }
            catch (Exception e)
            {
                System.Net.Sockets.SocketException errnum = new System.Net.Sockets.SocketException();
                // .ErrorCode()
                string aa;
                switch (errnum.ErrorCode)
                {
                    case 10060:
                        MessageBox.Show("Could not connect to the 2701, please recheck your connections and network settings and try again ", "Time Out Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        break;
                    case 10061:
                        MessageBox.Show("Could not open connection because instrument has an open connection to another application.  Close th" +
                             "e connected application or power cycle the instrument to close existing connection", "Connection Refused !", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        MessageBox.Show(("Error has occured:  "
                              + (errnum.ErrorCode + ("  " + e.Message))), "Error has been detected !", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        break;
                }
            }
        }
 
        public void config()
        {
 
                try
            {
                //// Commented out for Dart compatibility 01/31/07 : JV
                this.KI2701Client.ReceiveTimeout = 0;
                this.KI2701Client.SendTimeout = 0;
 
                this.send("*RST\r\n");//error 110
                //tcp2701.send("*IDN?\r\n");
                this.send("FORM:ELEM READ,CHAN\r\n");
                this.send("DISP:ENAB ON\r\n");
                this.send("INIT CONT OFF\r\n");
                this.send("TRIG:SOUR TIM\r\n");
                this.send("TRIG:TIM 5\r\n");
 
                this.send("TRAC:CLE\r\n");
                this.send("TRIG:COUN 1\r\n");
                this.send("SAMP:COUN 1\r\n");
                this.send("ROUT:SCAN (@101)\r\n");
                this.send("ROUT:SCAN:TSO IMM\r\n");
                this.send("ROUT:SCAN:LSEL INT\r\n");
                this.send("TRAC:FEED:CONT NEXT\r\n");
                this.send("INIT\r\n");
                this.configok = true;
 
 
                }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
 
            }
        }
 
        public void disconnect()
        {
            if ((connected == true))
            {
                send("*rst");
                connected = false;
                KI2701Stream.Close(0);
                KI2701Client.Close();
                KI2701Client = null;
                
                dis = true;
            }
            connected = false;
        }
 
        public void KI2701send(string data)
        {
            // Send data
            byte senddata;
        }
 
        public void KIInput(ref string KIstatus)
        {
            string myval = "";
            send("SYST:FRSW?");
           // myval = KI2701Read(ref string KIData);
            myval = read();
            if ((KIData == "1"))
            {
                KIstatus = "Front";
            }
            else
            {
                KIstatus = "Rear";
            }
        }
 
        public string read()
        {
            string ival = "";
            ival = this.KI2701Read( ref ival);
            return ival;
        }
 
        public string KI2701Read(ref string KIdata)
        {
            //  Read network stream into byte buffer
 
            try
            {
                
                byte[] bytes = new byte[KI2701Client.ReceiveBufferSize];
                KI2701Stream.Read(bytes, 0, KI2701Client.ReceiveBufferSize);
                KIdata = System.Text.ASCIIEncoding.ASCII.GetString(bytes);
                if (KIdata != null)
                {
                    this.thevalue = KIdata.ToString();
                    return this.thevalue;
                }
                else
                {
                    return "-";
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
 
            return string.Empty;
 
            //  Debug.WriteLine(KIdata)
        }
 
        public void close()
        {
            this.close();
        }
 
    }
 
 
 
}
 

Open in new window

0
gnoonCommented:
Try to add one more boolean flag in General class, just like connected but named isreading. Check for this flag in both disconnect() and KI2701Read().
        public void disconnect()
        {
            while(isreading)
            {   // wait here until read operation is finished
                // sleep for awhile to not use more ability of CPU
                try { System.Threading.Thread.Sleep(1000); } catch(Exception){}
            }
            if ((connected == true))
            {
                send("*rst");
                connected = false;
                KI2701Stream.Close(0);
                KI2701Client.Close();
                KI2701Client = null;
                
                dis = true;
            }
            connected = false;
        }
 
        public string KI2701Read(ref string KIdata)
        {
            // set flag before read
            isreading = true;
 
            // Read network stream into byte buffer
            try
            {
                byte[] bytes = new byte[KI2701Client.ReceiveBufferSize];
                KI2701Stream.Read(bytes, 0, KI2701Client.ReceiveBufferSize);
                KIdata = System.Text.ASCIIEncoding.ASCII.GetString(bytes);
                if (KIdata != null)
                {
                    this.thevalue = KIdata.ToString();
                    return this.thevalue;
                }
                else
                {
                    return "-";
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
            finally
            {
                // reset flag after read
                isreading = false;
            }
            return string.Empty;
 
            //  Debug.WriteLine(KIdata)
        }

Open in new window

0
jvalescuAuthor Commented:
Still getting the same error, but this time I don't get the second error.  I think we are getting close!

 public void disconnect()
        {
 
            while (isreading)
            {   // wait here until read operation is finished
                // sleep for awhile to not use more ability of CPU
                try { System.Threading.Thread.Sleep(1000); }
                catch (Exception) { }
            }
 
            if ((connected == true))
            {
                send("*rst");
                connected = false;
                KI2701Stream.Close(0);
                KI2701Client.Close();
                KI2701Client = null;
                
                dis = true;
            }
            connected = false;
        }
 
 public string KI2701Read(ref string KIdata)
        {
 
            // set flag before read
            isreading = true;
 
            //  Read network stream into byte buffer
 
            try
            {
 
                
                byte[] bytes = new byte[KI2701Client.ReceiveBufferSize];
                KI2701Stream.Read(bytes, 0, KI2701Client.ReceiveBufferSize);
                KIdata = System.Text.ASCIIEncoding.ASCII.GetString(bytes);
                if (KIdata != null)
                {
                    this.thevalue = KIdata.ToString();
                    return this.thevalue;
                }
                else
                {
                    return "-";
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
            finally
            {
                // reset flag after read
                isreading = false;
            }
 
            return string.Empty;
 
            //  Debug.WriteLine(KIdata)
        }

Open in new window

sshot-7.jpg
0
jvalescuAuthor Commented:
Do you think it could it could have something with the ReceiveTimeout property?  I found this:

The WSACancelBlockinCall exception generally happens when you stop
listening.  Listen is a blocking method.  When you stop it by closing the
socket or for other reasons, that is the error you get.  The following
seems, though, to be your problem and is quoted from the MSDN library
description for ReceiveTimeout:

The ReceiveTimeout property determines the amount of time that the Read
method will block until it is able to receive data. This time is measured in
milliseconds. If the time-out expires before Read successfully completes,
TcpClient will throw a SocketException. There is no time-out by default.

Not sure how to interpret it.  Any suggestions?
 public void config()
        {
 
                    try
            {
                //// Commented out for Dart compatibility 01/31/07 : JV
                this.KI2701Client.ReceiveTimeout = 0;
                this.KI2701Client.SendTimeout = 0;
 
                this.send("*RST\r\n");//error 110
                this.send("FORM:ELEM READ,CHAN\r\n");
                this.send("DISP:ENAB ON\r\n");
 
                this.send("INIT CONT OFF\r\n");
                this.send("TRIG:SOUR TIM\r\n");
                this.send("TRIG:TIM 5\r\n");
 
                this.send("TRAC:CLE\r\n");
                this.send("TRIG:COUN 1\r\n");
                this.send("SAMP:COUN 1\r\n");
                this.send("ROUT:SCAN (@101)\r\n");
                this.send("ROUT:SCAN:TSO IMM\r\n");
                this.send("ROUT:SCAN:LSEL INT\r\n");
                this.send("TRAC:FEED:CONT NEXT\r\n");
                this.send("INIT\r\n");
                this.configok = true;
 
 
      	}
 
 
 
 
 
        
 
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
 
            }
        }

Open in new window

0
gnoonCommented:
What I can see is the error will be thrown only when you clicked on stop button. So, the cause should be there at stop code. The most possible code is <code>this.tcp2701.disconnect();</code> which does a lot things within disconnect().

Back to the error message, it's related with read exception. The read was instantly blocked by something in between, to be consistent with disconnect() and I think it's blocking the read operation.

To prevent this error, what I think, is you should provide a mechanism to wait for a moment until read operation finished just before you close the stream.

I dont think ReceiveTimeout is the root cause because you said it work fine until clicking on stop button. Why you?
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.