EMX - SocketException after HttpWebRequest

Greetings everybody,
after few hours of trying to solve this by myself, I’m starting to be desperate, so I would like to ask if anyone experienced following behavior:

My application has main screen where end-user can put widgets. One of these widgets uses HttpWebRequest to retreive weather information from web-site. Everything worked just fine after I switched from 4.1 SDK to newest 4.2 SDK (VS2010 - so I’m using .NETMF 4.2 QFE). After system startup, widget updates itself without any problem for a few times (40 - 60 times), but after then it fails raising webexception, which has interesting inner exception:


 ### Exception System.Net.Sockets.SocketException - CLR_E_FAIL (6) ####
    #### Message: 
    #### Microsoft.SPOT.Net.SocketNative::recv [IP: 0000] ####
    #### System.Net.Sockets.Socket::Receive [IP: 0018] ####
    #### System.Net.Sockets.NetworkStream::Read [IP: 0062] ####
    #### System.Net.InputNetworkStreamWrapper::RefillInternalBuffer [IP: 0038] ####
    #### System.Net.InputNetworkStreamWrapper::Read_HTTP_Line [IP: 004b] ####
    #### System.Net.HttpWebRequest::ParseHTTPResponse [IP: 002e] ####
    #### System.Net.HttpWebRequest::GetResponse [IP: 0035] ####
    #### Fides.Asset.TouchPanel.Widget.Information.AbstractBarinkaTestWidget::UpdateWidget [IP: 001f] ####
    #### Fides.Asset.TouchPanel.Widget.WidgetManager::update [IP: 0063] ####
    #### Fides.Asset.TouchPanel.Widget.WidgetManager::updateThread_Worker [IP: 0012] ####
    #### SocketException ErrorCode = -1728053248
    #### SocketException ErrorCode = -1728053248
A first chance exception of type 'System.Net.Sockets.SocketException' occurred in Microsoft.SPOT.Net.dll

I catch this exception and try it again after few seconds. But this second try hangs when calling:


using (HttpWebResponse wr = (HttpWebResponse)request.GetResponse())

and never returns.

The whole code looks like these:


using (HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri(@ "http://www.webcamlive.cz/xml_measureById.php?idMeasure=" + Parameters)))
{
   request.UserAgent = "Touch Panel";

   using (HttpWebResponse wr = (HttpWebResponse)request.GetResponse())
   {
      using (Stream s = wr.GetResponseStream())
      {
         using (XmlReader xml = XmlReader.Create(s))
         {
            // just simple xml reading, nothing interesting
            xml.Close();
         }
         s.Close();
      }
      wr.Close();
   }
}

Has anyone an idea what the ErrorCode -1728053248 (0xFF000000) means? Has anyone ever experienced this behaviour afer switching to 4.2?

Thank you
Martin

Just to confirm that I have the same issue on a G120 with the latest firmware.
And I don’t use HttpWebRequest, just plain TCP client socket.
The exception I often get is : -1728053248, but I got other exceptions as well.
Same behavior, it works maybe for the first 40 to 1250 times.
If I only do “connects” without transmitting any data, it takes a while until I get an exception, but eventually, it happened around the 1250th connection.
If I connect to the server, and transmit back and forth 3kbytes messages for a little while, eventually I get an exception.
Once the exception happens, I cannot ever reconnect to the server, without rebooting the G120.

Here is my client code:

using System;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.Text;
using Microsoft.SPOT;
using Microsoft.SPOT.Net.NetworkInformation;

namespace DataLoggerCommonLib {
    public class SocketClient : Disposable {

        public System.Threading.Thread mSocketClientThread = null;
        public bool mNetworkAvailable = false;
        public bool mConnected = false;
        public string mServerIP;
        public int mServerPort;
        private int mTimeoutMillis = 5*1000; // Après 60 secondes sans communications du serveur, on essait de se reconnecter
        public object ThreadMutex = new object();
        private bool mClosingThread = false;
        private int mNumSocket = 0;

        private DateTime mTimeLastCommunication = DateTime.Now;

        private Byte[] mCommBuffer = new Byte[65536];

        public SocketClient(string serverIP, int serverPort) {
            this.mServerIP = serverIP;
            this.mServerPort = serverPort;
            
        }


        public void VerifyConnectionIsAlive() {
            TimeSpan verifyExpired = DateTime.Now - mTimeLastCommunication;
            //If time since last communication has expired...
            if (mSocketClientThread == null || CommonTools.ConvertTimeSpanToMillis(verifyExpired) >= mTimeoutMillis) {
                Debug.Print("Server not responding for a while. Restarting connection...");
                mClosingThread = true;
                mConnected = false;
                               
                try {
                    if (mSocketClientThread != null) {
                        if ( mSocketClientThread.Join(5000) ) {
                            Debug.Print("SocketClient Thread Join successful.");
                        } else {
                            Debug.Print("SocketClient Thread Join FAILED, closing socket and trying again.");
                            //CloseSocket();
                            if (mSocketClientThread.Join(5000)) {
                                Debug.Print("SocketClient Thread Join successful after 2nd try.");
                            } else {
                                Debug.Print("Thread Join FAILED, aborting thread.");
                                try {
                                    if (mSocketClientThread != null) {
                                        mSocketClientThread.Abort();
                                        
                                    }
                                } catch {
                                }
                                Thread.Sleep(5000);
                            }
                        }
                        
                        mSocketClientThread = null;                        
                    }
                } catch  {
                }
                
                mSocketClientThread = null;
                Thread.Sleep(1000);
                Debug.GC(true);
                GC.WaitForPendingFinalizers();

                mClosingThread = false;
                ConnectToServerAndKeepAlive();

            }

        }
        
        public void ConnectToServerAndKeepAlive() {            
            mTimeLastCommunication = DateTime.Now;
            mSocketClientThread = new System.Threading.Thread(StartConnectionBackGround);
            mSocketClientThread.Start();
        }

        private void StartConnectionBackGround() {
            mTimeLastCommunication = DateTime.Now;

            Socket socket = Connect();
            if ( socket != null ) {
                mNumSocket++;
                Debug.Print("NumSocket:" + mNumSocket);
                //this.WaitForCommands(socket);
            }
            CloseSocket(socket);
            
        } 


        public Socket Connect() {
            bool linger = false;
            Debug.GC(true);
            Thread.Sleep(100);
            Socket socket = null;
            try {
                IPHostEntry hostEntry = Dns.GetHostEntry(mServerIP);
                if (hostEntry != null && hostEntry.AddressList.Length > 0) {

                    socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    socket.ReceiveTimeout = 10000;
                    socket.SendTimeout = 10000;
                
                    IPEndPoint endPoint = new IPEndPoint(hostEntry.AddressList[0], mServerPort);
                    if (endPoint != null) {
                        socket.Connect(endPoint);
                        if (linger) {
                            socket.SetSocketOption(SocketOptionLevel.Socket
                                   , SocketOptionName.DontLinger, true);
                        } else {
                            socket.SetSocketOption(SocketOptionLevel.Tcp
                                , SocketOptionName.NoDelay, true);
                        }
                        mNetworkAvailable = true;
                        mConnected = true;
                    } else {
                        Debug.Print("Unable to determine Host Address");
                        return null;
                    }
                } else {
                    Debug.Print("Unable to resolve DNS entry");
                    return null;
                }
           
            } catch (Exception ex) {
                Debug.Print("Server not responding..." + ex.Message);
                return null;
            }

            return socket;
        }

        public void WaitForCommands(Socket socket) {
            Debug.Print("Connection OK, waiting for command");
            try {
                //do {
                    // Wait for the client request to start to arrive.
                    if (socket != null) {
                        //if (socket.Poll(15000000, SelectMode.SelectRead)) {

                            while (socket.Available != 0) {
                                mTimeLastCommunication = DateTime.Now;

                                Int32 bytesRead = socket.Receive(mCommBuffer, socket.Available, SocketFlags.None);

                                string request = CommonTools.DecodeHttpRequest(CommonTools.BytesToString(mCommBuffer, bytesRead));
                                Debug.Print(request);
                                //string responseString = decode_request(request);
                                string responseString = logger.HttpProcessor.processHttpRequest(request);
                                // Return a static HTML document to the client.
                                String str = "HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\nContent-Length: " + responseString.Length + "\r\n\r\n" + responseString;

                                socket.Send(Encoding.UTF8.GetBytes(str));
                                mTimeLastCommunication = DateTime.Now;
                                Debug.GC(true);
                                GC.WaitForPendingFinalizers();
                                Thread.Sleep(1000);
                            }
                        //}
                    }
                    Thread.Sleep(100);
                //} while (!mClosingThread);
            } catch (Exception ex) {
                Debug.Print("Error while processing commands. Reconnecting..." + ex.Message);
            }            
        }
        
        private void CloseSocket(Socket socket) {
            try {
                if (socket != null) {
                    socket.Close();
                }
            } catch {
            }
            socket = null;
        }
        
        protected override void ReleaseManagedResources() {
            
        }
        
    }
}

For now I will make my server to communicate with the G120 devices, but I would eventually need the G120 to connect as client to the server because of firewall/routing issues.

If it helps, I could provide a fully functionnal VS2010 solution/project to show the socket exceptions I am getting.
By the way, this is with an ENC28J60 module.

I ran this on a spider and it works fine. If this is all the code did you setup the network?
What is the value of parameters?

Ok, I reran it and it gets the exception every other time it executes. Something is not getting closed.

@ Marten -

OK, This works.

Add the KeepAlive = false;

The server is keeping the connection open.

request.UserAgent = "Touch Panel";
                request.KeepAlive = false;

Hi, thank you for your reply

I tried to set KeeAplive property to false and the behavior is different but not good at all. It just stopped to throw SocketException as I described in my first post, but after few successful updates, it just hangs on calling:


using (HttpWebResponse wr = (HttpWebResponse)request.GetResponse())

but this time without any preceeding exceptions.

I don’t understand your sentence:

I closed and disposed everuthing properly so I don’t understand why should anything stay opened?

Thank you
Martin

I’m starting to believe that it’s connected with problem described in this thread http://www.ghielectronics.com/community/forum/topic?id=11465

It seems that it’s a suicide to release product version with .NETMF 4.2 QFE + GHI Premium 4.2.10.1 :frowning:

I must not have ran it long enough. What is the value of "parameters " that way I can see what your seeing.

When I said the server is keeping the connection open is because of the “idealize” = true.

“Parameters” is just string property contained in abstract class of widget which holds value in format depending on specific widget implementation. In case of weather widget it represents ID of measure. You can test it for example with value 61 to see temperature in my home city :slight_smile:

That should have read "keepalive " .
I am running your code with a timer and that may be the difference based on what I read in the other thread concerning the need for the sleep call. Will let you know.

OK, thanks, let me know about your results. I’m running the code in separated thread… I tried to add Sleep and calling Debug.GC(true) according to topic I’ve posted above, but with no luck.

This is running and the count is over 400 with no errors.

int count = 0;
            while (true)
            {
                using (HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri(@ "http://www.webcamlive.cz/xml_measureById.php?idMeasure=" + 61)))
                {
                    request.UserAgent = "Touch Panel";
                    request.KeepAlive = false;

                    using (HttpWebResponse wr = (HttpWebResponse)request.GetResponse())
                    {
                        using (Stream s = wr.GetResponseStream())
                        {
                            using (XmlReader xml = XmlReader.Create(s))
                            {
                                //while (xml.Read()) logdebug("xml: " + xml.Name);
                                xml.Close();
                            }
                            if((count++ % 100) == 0) logdebug("Response: " + count);
                            s.Close();
                        }
                        wr.Close();
                    }
                }
            }

you can contact me @ “cowboy@ ranch.com” and I can send you my project if you want.

Uh, now I really don’t understand why you can run my code without any problem? Are you sure you’re using 4.2 .NETMF? Are you using EMX as well?

Yes 4.2 Spider.

Pinging… Pinging… TinyCLR
HalSystemInfo.halVersion: 4.2.0.0
HalSystemInfo.halVendorInfo: Microsoft Copyright © Microsoft Corporation. All rig
HalSystemInfo.oemCode: 255
HalSystemInfo.modelCode: 0
HalSystemInfo.skuCode: 65535
HalSystemInfo.moduleSerialNumber: FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
HalSystemInfo.systemSerialNumber: FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
ClrInfo.clrVersion: 4.2.0.0
ClrInfo.clrVendorInfo: Microsoft Copyright © Microsoft Corporation. All rig
ClrInfo.targetFrameworkVersion: 4.2.0.0
SolutionReleaseInfo.solutionVersion: 4.2.9.0
SolutionReleaseInfo.solutionVendorInfo: Copyright © GHI Electronics, LLC
SoftwareVersion.BuildDate: Feb 13 2013
SoftwareVersion.CompilerVersion: 410713
FloatingPoint: True
SourceLevelDebugging: True
ThreadCreateEx: True
LCD.Width: 320
LCD.Height: 240
LCD.BitsPerPixel: 16
AppDomains: True
ExceptionFilters: True
IncrementalDeployment: True
SoftReboot: True
Profiling: False
ProfilingAllocations: False
ProfilingCalls: False
IsUnknown: False

OK, I created very simple project:


    public class Program
    {
        private static EthernetBuiltIn ethernet;

        public static void Main()
        {
            ethernet = new EthernetBuiltIn();
            ethernet.NetworkAddressChanged += new NetworkInterfaceExtension.NetworkAddressChangedEventHandler(ethernet_NetworkAddressChanged);
            ethernet.CableConnectivityChanged += new EthernetBuiltIn.CableConnectivityChangedEventHandler(ethernet_CableConnectivityChanged);
            ethernet.Open();

            NetworkInterfaceExtension.AssignNetworkingStackTo(ethernet);
            ethernet.NetworkInterface.EnableDhcp();

            new Thread(testThread_Work).Start();

            while (true)
            {
                Thread.Sleep(5000);
            }
        }

        private static void ethernet_CableConnectivityChanged(object sender, EthernetBuiltIn.CableConnectivityEventArgs e)
        {
            logDebug("Network cabel " + (e.IsConnected ? "connected" : "disconnect"));
        }

        private static void ethernet_NetworkAddressChanged(object sender, EventArgs e)
        {
            logDebug("Network address changed :: " + ethernet.NetworkInterface.IPAddress);
        }

        private static void testThread_Work()
        {
            int count = 0;
            while (true)
            {
                using (HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri(@ "http://www.webcamlive.cz/xml_measureById.php?idMeasure=" + 61)))
                {
                    request.UserAgent = "Touch Panel";
                    request.KeepAlive = false;

                    using (HttpWebResponse wr = (HttpWebResponse)request.GetResponse())
                    {
                        using (Stream s = wr.GetResponseStream())
                        {
                            using (XmlReader xml = XmlReader.Create(s))
                            {
                                //while (xml.Read()) logdebug("xml: " + xml.Name);
                                xml.Close();
                            }
                            if ((count++ % 100) == 0)
                            {
                                logDebug("Response: " + count);
                            }

                            s.Close();
                        }
                        wr.Close();
                    }
                }
            }
        }

        private static void logDebug(string text)
        {
            Debug.Print(text);
        }
    }

Sometimes I can even reach debu output “Response: 501”, but it was my top, after that garbage collection occured and it hangs again. Never happend with .NETMF 4.1 before :frowning:

I don’t use “EthernetBuiltIn();”

Could I send you my project?
cowboy@ ranch.com

try enabling dhcp before assigning network to stack

Try this:


public class Program
    {
        private static EthernetBuiltIn ethernet;
 
        public static void Main()
        {
            ethernet = new EthernetBuiltIn();
            ethernet.NetworkAddressChanged += new NetworkInterfaceExtension.NetworkAddressChangedEventHandler(ethernet_NetworkAddressChanged);
            ethernet.CableConnectivityChanged += new EthernetBuiltIn.CableConnectivityChangedEventHandler(ethernet_CableConnectivityChanged);
            ethernet.Open();
 
			ethernet.NetworkInterface.EnableDhcp();  // Moved here as Mike suggested
            NetworkInterfaceExtension.AssignNetworkingStackTo(ethernet);
           
 
            new Thread(testThread_Work).Start();
 
            while (true)
            {
                Thread.Sleep(5000);
            }
        }
		static Boolean isReady = false;
        private static void ethernet_CableConnectivityChanged(object sender, EthernetBuiltIn.CableConnectivityEventArgs e)
        {
            logDebug("Network cabel " + (e.IsConnected ? "connected" : "disconnect"));
        }
 
        private static void ethernet_NetworkAddressChanged(object sender, EventArgs e)
        {
            logDebug("Network address changed :: " + ethernet.NetworkInterface.IPAddress);
			if (ethernet.NetworkInterface.IPAddress != "0.0.0.0") // please correct it, I just type out my idea :))
			{
				isReady = true;
			}
			else 
			{
				isReady = false;
			}
        }
 
        private static void testThread_Work()
        {
            int count = 0;
            while (true)
            {
				if (isReady == true)
				{
					using (HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri(@ "http://www.webcamlive.cz/xml_measureById.php?idMeasure=" + 61)))
					{
						request.UserAgent = "Touch Panel";
						request.KeepAlive = false;
	 
						using (HttpWebResponse wr = (HttpWebResponse)request.GetResponse())
						{
							using (Stream s = wr.GetResponseStream())
							{
								using (XmlReader xml = XmlReader.Create(s))
								{
									//while (xml.Read()) logdebug("xml: " + xml.Name);
									xml.Close();
								}
								if ((count++ % 100) == 0)
								{
									logDebug("Response: " + count);
								}
	 
								s.Close();
							}
							wr.Close();
						}
					}
				}
				Thread.sleep(100);
            }
        }
 
        private static void logDebug(string text)
        {
            Debug.Print(text);
        }
    }

Hi Dat,

Would this also be recommended for static IP, enable it before assigning the network stack?