Link to home
Start Free TrialLog in
Avatar of u2envy1
u2envy1

asked on

A connect request was made on an already connected socket Async

I get the following error when sending the data to a device the second time.
I send a command the second time because of the value the device returns.
How can I prevent this error from happening & get my second command to the device.
public override void SendData(string data)
        {
            try
            {
 mSocket.BeginSendTo(bufferNew, 0, bufferNew.Length, SocketFlags.Partial, mIPEndPoint, new AsyncCallback(EndSend), null);
                //mSocket.Send(bufferNew);
 
                mSocket.Listen(5000);//Keep port open to listen for incoming data
 
                mSocket.BeginAccept(OnDataReceived, mSocket);
                
 
            }
            catch (SocketException se)
            {
                string err = se.ToString();
                
            }
 
 public void EndSend(IAsyncResult asyncResult)
        {
            mSocket.EndSend(asyncResult);
            mSocket.EndAccept(asyncResult);
            mSocket.Disconnect(true);
        }
 
byte[] m_DataBuffer;
        public void WaitForData()
        {
            m_DataBuffer = new byte[256];
            if (pfnCallBack == null)
            {
                pfnCallBack = new AsyncCallback(OnDataReceived);
            }
            // now start to listen for any data... 
            m_asynResult = mSocket.BeginReceive(m_DataBuffer, 0, m_DataBuffer.Length, SocketFlags.None, pfnCallBack, null);           
           
           
        }
        public void OnDataReceived(IAsyncResult asyn)
        {
            //end receive...
            int iRx = 0;
            try
            {
                if (m_asynResult.AsyncWaitHandle.WaitOne())
                {
                    iRx = mSocket.EndReceive(asyn);
                    char[] chars = new char[iRx + 1];
                    char[] charsNew = new char[iRx];//Decoder adds 65533 to starting char. Used to remove the first value 655355
                    Decoder d = Encoding.UTF8.GetDecoder();
                    int charLen = d.GetChars(m_DataBuffer, 0, iRx, chars, 0);
                    chars[0] = ((char)1);
                    Array.Copy(chars, 1, charsNew, 0, iRx);
                    String szData = new String(chars);
 
                    foreach (var item in chars)//Add info to Mylist to be returned
                    {
                        myList.Add(Convert.ToByte(item));
                    }
                    if (szData.Length == 0)//If no data recieved check again for data
                    {
                        WaitForData();//Method to check for data
 
                    }                  
                }
 
            }
            catch (SocketException ex)
            {
                string m = ex.ToString();
            }
                     
            
        }

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of SaedSalman
SaedSalman
Flag of Jordan image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of u2envy1
u2envy1

ASKER

How do I prevent this from happening ?
Hello U2...,  I am not sure if this is the problem but I have had and cured the exact same problem with a TELNET client app I created.  Forgive me for being/doing this in VB rather than C#, but since this only an issue of concepts, the important point will be explained:
I believe it is an issue of where the declaration of the TCP client is located - as they would say a scoping issue.  I started with my statement located in the declarations level:

                  Private myClient as New TCPClient

followed by the function that used it:
                  Public Function Connect(byval HOSTID as string) as boolean
                       myClient.connect(HOSTID, 23)
                       myStream = myClient.GetStream()

 The client would open and be used then close all just fine.  Then when my app would go to open it (eg client.connect) for a 2nd time, I would get the infamous message " connection request was made on an already connected socket" etc.  You cant just close the client at that point, as then you let it fall into the garbage pail and can not access it in your open routine as there is no way to invoke the creation of the object (not that I could figure out anyway).  But then I had the brainstorm:  move the declaration into the connection routine, it's only used there long enough to create the stream object, then the garbage collector will toss it long before you get to your disconnect routine (I suppose you could have a myClient.close in the disconnect routine, but its not necessary).

                  Public Function Connect(byval HOSTID as string) as boolean
                      dim myClient as New TCPClient
                       myClient.connect(HOSTID, 23)
                       myStream = myClient.GetStream()

This way the object is created for each new call to the function, then destroyed when it falls out of scope (boy is that new behavior an adjustment to get used to in .NET!).