Main Site Documentation

Handling Network Interruption for Sockets


#1

So my device will constantly be awaiting a socket connection using the following code:


X509Certificate cert = new X509Certificate(Resources.GetBytes(Resources.BinaryResources.certificate), password);
            Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, relayPort);
            server.Bind(localEndPoint);
            server.Listen(5);
            while (true)
            {
                try
                {
                    // accept client connections
                    Debug.Print("wait for Connect");
                    Socket Client = server.Accept();
                    SslStream s = new SslStream(Client);
                    s.AuthenticateAsServer(cert, SslVerification.NoVerification, SslProtocols.Default);
                    byte[] receivedFromClient = ReceiveClientData(Client, s);
                    String receivebuffer = new string(Toolbox.NETMF.Tools.Bytes2Chars(receivedFromClient));

                    if (receivebuffer.Length > 0 && receivebuffer.Equals("something"))
                    {
                        do something...
                    }
                    if (receivebuffer.Length > 0 && receivebuffer.Equals("something else"))
                    {
                        do something else...
                    }

                    Debug.Print(receivebuffer);
                    s.Write(ConvertStringForMessage("respond"), 0, ConvertStringForMessage("respond").Length);
                    s.Dispose();
                    Client.Close();
                }
                catch(Exception ex)
                {
                    Debug.Print(ex.Message);
                    break;
                }
            }
            Debug.Print("Relay Thread Ending");

Now when I simulate a network outage the socket errors as expected:
#### Exception System.Net.Sockets.SocketException - CLR_E_FAIL (10) ####
#### 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
#### SocketException ErrorCode = 10050
#### SocketException ErrorCode = 10050
Exception was thrown: System.Net.Sockets.SocketException

The question is…what is the correct way to handle a network outage for this socket… Then recreating the socket connection with the same function?


#2

how did you initialize the network?


#3

Network Initialize:


if (!wifi_RS21.Interface.IsOpen)
                wifi_RS21.Interface.Open();
            if (!wifi_RS21.Interface.NetworkInterface.IsDhcpEnabled)
                wifi_RS21.Interface.NetworkInterface.EnableDhcp();
            NetworkInterfaceExtension.AssignNetworkingStackTo(wifi_RS21.Interface);
            wifi_RS21.Interface.WirelessConnectivityChanged += new WiFiRS9110.WirelessConnectivityChangedEventHandler(Interface_WirelessConnectivityChanged);
            wifi_RS21.Interface.NetworkAddressChanged += new NetworkInterfaceExtension.NetworkAddressChangedEventHandler(Interface_NetworkAddressChanged);

try
            {
                Debug.Print("Scan for wireless networks");
                WiFiNetworkInfo[] scanResult = wifi_RS21.Interface.Scan(WifiName);
                if (scanResult != null && scanResult.Length > 0)
                {
                    Debug.Print("Connecting to " + WifiName);
                    try
                    {
                        wifi_RS21.Interface.Join(scanResult[0], WifiPass);
                        Debug.Print("Connected");
                    }
                    catch (Exception e)
                    {
                        Debug.Print(e.Message + e.InnerException);
                        Debug.Print("Can't connect");
                    }
                }
                else
                {
                    Debug.Print(WifiName + " Wireless network was not found");
                }
            }
            catch (Exception e)
            {
                Debug.Print(e.Message);
            }



#4

initial looks. good. are you checking that the network is up before doing the accept? does the 10050 happen. the first time the accept is issued?


#5

Everything works fine normal situation. However, take network down. Bring network back. Socket doesn’t work anymore.


#6

Tried the reuse option and got same results. Sounds like I need to somehow block the accept when the network goes down. Not sure how to though.


#7

@ chad21mycoopers - close listening socket and wait for network to be restored. then start again.


#8

In the end I don’t believe is was a coding issue. Apparently the issue was in the router. I added the line:

server.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.ReuseAddress, true);

and

server.Close()

Everything is working as expected now…after resolving the router issue.

Thanks for the help everyone.