Main Site Documentation

Cerberus w. Ethernet blocking after removing ethernet cable, how to avoid?


#1

Hi,

I’m running a TCP listening server on my Cerberus with ethernet board.
If I remove the ethernet cable the cerberus runs into an loop of throwing exceptions “System.Net.Sockets.SocketException in Microsoft.SPOT.Net.dll” all the time.

Stack trace:
Microsoft.SPOT.Net.SocketNative::poll
System.Net.Sockets.Socket::Poll
System.Net.Sockets.Socket::Accept
GadgeteerApp.TCPListenServer::StartServer

m_HResult: 4278190080

The StartServer-method contains the following statements:


Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, Tools.TcpPort);
server.Bind(localEndPoint);
server.Listen(1);
while (true)
{
    try
    {
        Socket clientSocket = server.Accept();
        new ProcessClientRequest(clientSocket, true);
    }
    catch { }
}

Is there a possibility to get the program back to normal operation after reconnecting the network cable?
At the moment it runs in the catch block but does not return to normal operation afterwards.


#2

just move your try/catch block upper level, for catching socket/bind/listen exceptions and check for NetworkChanges events to avoid looping uneedlessy over your accept/request lines


#3

You think I should put my ProcessClientRequest calls into a NetworkChanges-callback method, right?


#4

@ fp not sure about that because if you’re already connected or disconnected at start you won’t see any event. There is apparently no way to check network avalaibility when the code starts. But you could catch the exception first and decide it is a disconnection, stop the loop, wait for the avalaibility event fired up and start it again.


#5

I tried this in the following way:


static void NetworkChange_NetworkAvailabilityChanged(object sender, NetworkAvailabilityEventArgs e)
{
    if (e.IsAvailable)
    {
        bNetworkAvailable = true;
        ProgramStarted();
    }
    else
    {
        bNetworkAvailable = false;
    }
}

My loop now looks like this:


while (true && bNetworkAvailable)
{
...
     if (!bNetworkAvailable)
     {
          break;
     }
}

But the cerberus continues throwing exceptions. Is there any possibility to find out, if there’s another process which is throwing the socket exception? I think in my program, there is no other part that uses system.net.sockets.


#6

Couldn’t that just be…


while (bNetworkAvailable)
{
...
}

Also, its unusual to call ProgramStarted() from your own functions. Are you sure there’s nothing else in there that could be causing problems? ProgramStarted() is typically only called once in the life of a program.

You may also want to check out this thread where I was trying to achieve the same functionality. I haven’t checked my code with the latest firmware yet but jasdev appears to have found a workaround.

http://www.ghielectronics.com/community/forum/topic?id=10140&page=6#msg107726


#7

@ fp - like ianlee74 said, calling ProgramStarted in a Gadgeteer application is really weird.and should mess with a number of things I can’t fathom for the life of me. Check the coding guidelines for gadgeteer applications.

And “true && whatever” is equal to “whatever”, check your logic conditionnals.

You can’t avoid SocketException if you’re unplugging the cable in a middle of a socket operation. Just catch the exception, if you want that the thread triggering the exception to be still alive.


#8

Thank’s guys,

this was just a naive try to get out of the exception loop. I wanted to do something like a restart, if the network cable gets reconnected after having the exception.

The thread triggering the exception does not have to stay alive. The best solution was, if i could stop the connection process and wait until the cable is plugged in again.

I’ll try your suggestion, to remove the “true” condition.