G120 and Sockets, reliability problem - Need help!

But wouldn’t a "socket.Accept() " be in fact a loop polling the network for incoming connection ?
I have trouble seeing the difference between my own loop that does not break, but it does with a loop waiting for incoming network connection (I assume its a loop of some kind in the socket library)

So the workaround just delayed the problem, eventually the G120 are unreachable again after a few hours.
I will test some more today to know if if still blocks at socket.Accept()

I added the InstallConstraint() in code snippet I posted earlier
It does not appear to do anything, maybe I don’t use it right?
Still same problem, hit refresh many times in a browser, and eventually it blocks at socket.accept()


using System;
using System.Collections;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Controls;
using Microsoft.SPOT.Presentation.Media;
using Microsoft.SPOT.Touch;

using Gadgeteer.Networking;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using GHINET = GHI.Premium.Net;
using Microsoft.SPOT.Hardware;
using GHI.Premium.Hardware;
using GHI.Premium.Net;
using System.Net;
using System.Net.Sockets;
using System.Text;
using Gadgeteer.Modules.GHIElectronics;

namespace TestNetwork {
    public partial class Program {
        // This method is run when the mainboard is powered up or reset.   
        private Thread mainLoopThread;
        private Thread serverThread;
        private EthernetENC28J60 NetInterface;
        private Socket listenSocket;
        private Socket serverSocket = null;

        void ProgramStarted() {
            /*******************************************************************************************
            Modules added in the Program.gadgeteer designer view are used by typing 
            their name followed by a period, e.g.  button.  or  camera.
            
            Many modules generate useful events. Type +=<tab><tab> to add a handler to an event, e.g.:
                button.ButtonPressed +=<tab><tab>
            
            If you want to do something periodically, use a GT.Timer and handle its Tick event, e.g.:
                GT.Timer timer = new GT.Timer(1000); // every second (1000ms)
                timer.Tick +=<tab><tab>
                timer.Start();
            *******************************************************************************************/


            // Use Debug.Print to show messages in Visual Studio's "Output" window during debugging.
            Debug.Print("Program Started");

            InitNetwork();

            mainLoopThread = new Thread(MainLoop);
            mainLoopThread.Priority = ThreadPriority.Normal;
            mainLoopThread.Start();
        }


        private void InitNetwork() {

            try {
                //ethernet_ENC28 = new GHI.Premium.Net.EthernetENC28J60(SPI.SPI_module.SPI2, GHI.Hardware.G120.Pin.P1_17, GHI.Hardware.G120.Pin.P2_21, GHI.Hardware.G120.Pin.P1_14, 4000);
                NetInterface = ethernet_ENC28.Interface;

                NetInterface.CableConnectivityChanged += new GHI.Premium.Net.EthernetENC28J60.CableConnectivityChangedEventHandler(Interface_CableConnectivityChanged);
                NetInterface.NetworkAddressChanged += new GHI.Premium.Net.NetworkInterfaceExtension.NetworkAddressChangedEventHandler(Interface_NetworkAddressChanged);

                if (!NetInterface.IsOpen)
                    NetInterface.Open();

                GHI.Premium.Net.NetworkInterfaceExtension.AssignNetworkingStackTo(NetInterface);

                byte[] macAddress = new byte[] {0x00, 0x1c, 0x14, 0xf9, 0xda, 0xe9};
                for (int i=0;i<6;i++) {
                    if ( NetInterface.NetworkInterface.PhysicalAddress[i] != macAddress[i] ) {
                        NetInterface.NetworkInterface.PhysicalAddress = macAddress;  
                        Debug.Print("Updating MAC Address, please reboot for changes to take effect.");
                    }
                }

                if (!NetInterface.NetworkInterface.IsDhcpEnabled)
                    NetInterface.NetworkInterface.EnableDhcp();
                NetInterface.NetworkInterface.RenewDhcpLease();

            } catch (Exception ex) {
                Debug.Print("Error while initializing network" + ex.Message);
            }
        }


        void Interface_NetworkAddressChanged(object sender, EventArgs e) {
            Debug.Print("AddressChanged:" + NetInterface.NetworkInterface.IPAddress);

            if (NetInterface.NetworkInterface.IPAddress != "0.0.0.0") {
                StartServer();
            }
        }

        void Interface_CableConnectivityChanged(object sender, EthernetENC28J60.CableConnectivityEventArgs e) {
            Debug.Print("NetworkConnectChanged:" + e.IsConnected);

        }


        void StartServer() {

            serverThread = new Thread(ServerThread);
            serverThread.Priority = ThreadPriority.Normal;
            serverThread.Start();

        }

        byte[] request = new byte[65536];

        void ServerThread() {
            
            // Bind the listening socket to the port
            IPAddress hostIP = IPAddress.Parse(NetInterface.NetworkInterface.IPAddress);
            IPEndPoint ep = new IPEndPoint(hostIP, 80);
            listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            listenSocket.Bind(ep);

            // Start listening
            listenSocket.Listen(1);

            string msgStr = "Hello, browser! I think the time is " + DateTime.Now.ToString();
            string responseStr = "";
            for (int i = 0; i < 75; i++) {
                responseStr = responseStr + "\r" + msgStr;
            }


            byte[] messageBytes = Encoding.UTF8.GetBytes(responseStr);

            ExecutionConstraint.Install((int)(new TimeSpan(0, 0, 5)).Ticks, 0);

            // Main thread loop
            while (true) {
                try {
                    Debug.Print("listening...");
                    serverSocket = listenSocket.Accept();
                    Debug.Print("Accepted a connection from " + serverSocket.RemoteEndPoint.ToString());
                } catch (Exception e) {
                    Debug.Print("Exception @ listenSocket.Accept():" + e.Message);
                    continue;
                }
                
                if (!ReadAll()) {
                    continue;
                }

                try {
                    serverSocket.Send(messageBytes);

                } catch (Exception e) {
                    Debug.Print("Exception @ listenSocket.Send():" + e.Message);
                    if (ReadAll()) {
                    }
                    CloseSocket();
                    continue;
                }
                CloseSocket();
                serverSocket = null;
            }



        }

        bool ReadAll() {
            try {
                while (serverSocket.Poll(15000, SelectMode.SelectRead)) {
                    try {
                        int numBytes = serverSocket.Receive(request);
                        if (numBytes == 0) {
                            break;
                        }
                        Debug.Print("Receiving bytes(" + numBytes + "):" + Encoding.UTF8.GetChars(request).ToString());
                    } catch (Exception e) {
                        Debug.Print("Exception @ newSock.Receive():" + e.Message);
                        CloseSocket();
                        return false;
                    }
                }
            } catch (Exception e) {
                Debug.Print("Exception @ newSock.Poll():" + e.Message);
                CloseSocket();
                return false;
            }
            return true;
        }

        void CloseSocket() {
            try {
                serverSocket.Close();
            } catch (Exception e) {
                Debug.Print("Exception @ newSock.Close():" + e.Message);
            }
        }

        void MainLoop() {
            Thread.Sleep(-1);

        }
    }
}

Couple of things:

  1. I am only using it on outbound connections. Don’t know if that makes a difference.
  2. I uninstall the constraint at the end of every attempt.
    ie:
    ExecutionConstraint.Install(5000, 0);
    //Do the stuff that might cause a lockup
    ExecutionConstraint.Install(-1, 0);//uninstall constraint

Might be worth trying to move the install part to the beginning of your while loops and put the uninstall part at the end.

I just tried what you mentioned, without success :frowning:
It just stays at socket.Accept().
I could try with the G120 being a client , to see if that helps.

I will try also…i can get my to run for 24hours sometimes…and i have an application that does a request every 5 seconds…

It never seems to function more then 12hours most of the time…totally unreliable…i hope we can solve this issue soon?

I think the difference is, that socket.accept() calls a method of unmanaged code, that polls an Input pin.

I remember that I had the same problem with 4.1 too with an ftp client application. When the connection was broken the code did not return. I think, I started socket.accept from a separate thread that could be monitored for normal termination in a certain timespan.

I also tried the ‘watchdog with another thread method’ that will kill the socket thread if it blocks.
The problem is, it will block, and even if I restart the thread with a new socket.Accept(), nothing happens, it just hangs there.

@ PhilM -
have you tried

while (true) {
                try 
                 {
                    ExecutionConstraint.Install((int)(new TimeSpan(0, 0, 5)).Ticks, 0);
                    serverSocket = listenSocket.Accept();
                    ExecutionConstraint.Install(-1,0);
                     }
                    catch (ConstraintException)
                    {
                    Debug.Print("Constraint exception occured");
                    }
........
}
 

http://www2.f1.htw-berlin.de/scheibl/netMF/index.htm?./Basis/Schranke.htm

So far, the ConstraintException never happened (I can’t find a way to raise that exception at all!)

You can see in the following image that its stuck at listenSocket.Accept(), and if I try to connect it won’t respond (it did for a few times and eventually it does not respond)
http://s18.postimg.org/fj94bs9rd/network_problem_hang_socketaccept.png

And again this only does this problem with ENC28J60, not with wifi RS21 …

Still unreliable web server…when ever i get this exception…i can no longer get the server to block at

 using (connection = server.Accept())
 {
....

}
Socket waiting idle..
    #### Exception System.Net.Sockets.SocketException - CLR_E_FAIL (9) ####
    #### Message: 
    #### Microsoft.SPOT.Net.SocketNative::poll [IP: 0000] ####
    #### System.Net.Sockets.Socket::Poll [IP: 0011] ####
    #### System.Net.Sockets.Socket::Accept [IP: 0017] ####
    #### SocketException ErrorCode = 10050
    #### SocketException ErrorCode = 10050
A first chance exception of type 'System.Net.Sockets.SocketException' occurred in Microsoft.SPOT.Net.dll
Started server in thread 941608925
    #### SocketException ErrorCode = 10050
    #### SocketException ErrorCode = 10050
..server.Accept() failing

just to add to the story…i am using g120 Cobra 2 board

@ Zigbox, did you tried wifi as well and do you have the same problem ?

Hi,
I did not read your code thoroughly, but can it be that it is the same Problem as in this thread:
https://www.ghielectronics.com/community/forum/topic?id=9878&page=1
In this thread the reason (as I think) was that the socket buffer of the sending device got full.

I can confirm that I often received that exception (#### SocketException ErrorCode = 10050) when using Socket as a client (G120 => to PC)
Although the network was never down, it just broke by itself.

I am using wifi…i will try another wifi network to see if issue continues.

I have tried another wifi network and same issue…

    #### Exception System.Net.Sockets.SocketException - CLR_E_FAIL (5) ####
    #### Message: 
    #### Microsoft.SPOT.Net.SocketNative::poll [IP: 0000] ####
    #### System.Net.Sockets.Socket::Poll [IP: 0011] ####
    #### System.Net.Sockets.Socket::Accept [IP: 0017] ####
    #### SocketException ErrorCode = 10050
A first chance exception of type 'System.Net.Sockets.SocketException' occurred in Microsoft.SPOT.Net.dll
    #### SocketException ErrorCode = 10050
    #### SocketException ErrorCode = 10050
    #### SocketException ErrorCode = 10050

We will check to see what we can do,
Thanks

@ zigbox - what is the signal strength reported by your RS9110 module?

For everyones benefit…my DHCP client with Wifi appears to be now working…i didn’t change the code, i just commented out all other code in my application. It appears a reference or some other code is interrupting the wifi for an unknown reason.

I am going to step by step re-enable all my code back to its fullest to determine exactly where the wifi is disrupted. I will everyone know of my findings and hope it helps others.

GHI Forums is very useful and you guys rock!