Problem with Socket accept Method

Hi

I’m aware that same Questions have been asked in the past and I’m sorry for double posting but I didn’t quite find a solution in the threads.
I’m using the HomeOSGadgeteerLibrary which now runs on my FEZ Raptor. The Problem is that when calling the Accept Method my program just hangs forever. So what I tried is making a Thread and just join it after a timespan so I could reset the whole things, but I’m not very successful in doing this.
Is there a solution to my Problem?

Here’s the relevant code and the major issue is on line 12




```cs

protected void ProcessRequest()
            {
                // accept an incoming connection request and once we have one, spawn a new thread to accept more
                bool newThread = false;
                Socket clientSocket = null;
                Responder responder = null;
                while (IsRunning && !newThread)
                {
                    try
                    {
                        // process incoming request
                        Thread connectionThread = new Thread(() => { clientSocket = LocalServer.Accept(); }); //This call just hangs forever!! Thats why I put it into a thread!
                        connectionThread.Start();
                        connectionThread.Join(10000);

                        if (clientSocket == null)
                        {
                            Debug.Print("Resetting...");
                            //HOW?
                        }
                        else
                        {
                            Debug.Print("Got a connection!");

                            clientSocket.ReceiveTimeout = Timeout;
                            clientSocket.SendTimeout = Timeout;
                            // parse message an create an object containing parsed data 
                            responder = new Responder();
                            responder.ClientEndpoint = clientSocket.RemoteEndPoint.ToString();
                            responder.ClientSocket = clientSocket;

                            Debug.Print("Accepted connection from " + responder.ClientEndpoint);

                            Debug.Print("Thread: " + Thread.CurrentThread.ManagedThreadId + " accepted a socket!");
                        }
                        Thread t = new Thread(new ThreadStart(ProcessRequest));
                        t.Start();
                        newThread = true;
                    }
                    catch
                    {
                        if (clientSocket != null)
                        {
                            try
                            {
                                clientSocket.Close();
                            }
                            catch
                            {
                                
                            }
                        }
                    }
                }

                //actual processing of the request
               ...
                      
            }

I appreciate your help and hope we can find a solution to my problem

I use networking quite often, and the only hang problem I know about is when opening an TCP connection to another server.
I never had problems with accept.

1st:
how do you set up your local serer?
Eventually it’s not actually really waiting?

2nd:
Do you connect to your device? If no one connects. it is normal that Accept never returns.

3rd:
you need a try catch around the accept, or any exception there might blow up your program.

Cancel the accept:
You could call Cancel on the thread, but this might cause some unreleased resources.
It would be better to close your LocalServer socket. This should make Accept to throw an exception.

Here are some helper methods I made for TCP and UDP connections (with an timout for the some times hanging tcp connect):
The OpenTcpServer method does what is needed to prepare a socket before you call Accept on it.

   /// <summary>
   /// Utility class with network utilities
   /// </summary>
   public static class NetUtils
   {
      public static IPAddress ResolveHost(string host)
      {
         IPAddress ip;
         try
         {
            ip = IPAddress.Parse(host);
         }
         catch
         {
            var hostEntry = Dns.GetHostEntry(host);
            if (hostEntry.AddressList.Length == 0)
            {
               throw new InvalidOperationException("Could not resolve host name");
            }
            ip = hostEntry.AddressList[0];
         }
         return ip;
      }

      /// <summary>
      /// Opens a Tcp server connection
      /// </summary>
      /// <param name="port">Tcp port</param>
      /// <param name="backlog">Backlog count</param>
      /// <returns>Returns the Tcp server socket</returns>
      /// <remarks>
      /// Use the returned Tcp server socket to accept client connections.
      /// </remarks>
      public static Socket OpenTcpServer(int port, int backlog = 1)
      {
         var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
         IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, port);

         socket.Bind(localEndPoint);
         socket.Listen(backlog);
         return socket;
      }

      /// <summary>
      /// Opens a Tcp client connection
      /// </summary>
      /// <param name="ip">Server ip address</param>
      /// <param name="port">Server port</param>
      /// <returns>Returns the Tcp socket</returns>
      public static Socket OpenTcpClient(IPAddress ip, int port)
      {
         return OpenTcpClient(ip, port, -1);
      }

      /// <summary>
      /// Opens a Tcp client connection
      /// </summary>
      /// <param name="ip">Server ip address</param>
      /// <param name="port">Server port</param>
      /// <param name="timeout">Timeout in milliseconds</param>
      /// <returns>Returns the Tcp socket</returns>
      public static Socket OpenTcpClient(IPAddress ip, int port, int timeout)
      {
         var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
         if (timeout < 0)
         {
            socket.Connect(new IPEndPoint(ip, port));
         }
         else
         {
            var doneEvent = new ManualResetEvent(false);
            Exception connectException = null;
            var thread = new Thread(() =>
            {
               try
               {
                  socket.Connect(new IPEndPoint(ip, port));
                  doneEvent.Set();
               }
               catch (Exception ex)
               {
                  connectException = ex;
                  try
                  {
                     doneEvent.Set();
                  }
                  catch
                  {}
               }
            });
            thread.Start();
            try
            {
               if (doneEvent.WaitOne(timeout, false))
               {
                  if (connectException != null)
                  {
                     throw connectException;
                  }
               }
               else
               {
                  throw new TimeoutException();
               }
            }
            finally
            {
               if (thread.IsAlive)
               {
                  try
                  {
                     thread.Abort();
                  }
                  catch { }
               }
            }
         }
         return socket;
      }

      /// <summary>
      /// Creates an Udp socket
      /// </summary>
      /// <returns>Returns the Udp socket</returns>
      /// <remarks>
      /// The Udp socket is created but not bound or connected
      /// </remarks>
      public static Socket CreateUdpSocket()
      {
         return new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
      }

      /// <summary>
      /// Opens and Udp socket and binds it to a port
      /// </summary>
      /// <param name="port">Udp port</param>
      /// <returns>Returns a bound Udp socket</returns>
      public static Socket OpenUdpServer(int port)
      {
         var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
         try
         {
            socket.Bind(new IPEndPoint(IPAddress.Any, port));
            return socket;
         }
         catch
         {
            socket.Close();
            throw;
         }
      }

      /// <summary>
      /// Opens a Udp scoket and connects it to a remote ip
      /// </summary>
      /// <param name="ip">Remote ip address</param>
      /// <param name="port">Remote port</param>
      /// <returns>Returns the connect Udp socket</returns>
      public static Socket OpenUdpClient(IPAddress ip, int port)
      {
         var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
         try
         {
            socket.Connect(new IPEndPoint(ip, port));
            return socket;
         }
         catch
         {
            socket.Close();
            throw;
         }
      }

      /// <summary>
      /// Receives a number of bytes from an socket even if they are distributed over multiple ethernet frames.
      /// </summary>
      /// <param name="socket">Socket to receive from</param>
      /// <param name="data">Data array to write to</param>
      /// <param name="offset">Start index in data</param>
      /// <param name="size">Number of bytes to receive</param>
      /// <returns>True if all bytes where received; false if connection was interrupted</returns>
      public static bool Receive(Socket socket, byte[] data, int offset, int size)
      {
         int n = socket.Receive(data, offset, size, SocketFlags.None);

         if (n == 0)
         {
            return false;
         }
         int cnt = n;
         while (cnt < size)
         {
            n = socket.Receive(data, offset + cnt, size - cnt, SocketFlags.None);
            if (n == 0)
            {
               return false;
            }
            cnt += n;
         }
         return cnt == size;
      }
   }

Hi

I really appreciate your help i got some comments to your point:

1st: I now use your code to start the server socket.

public Socket OpenTcpServer(int port, string ipAddress ,int backlog = 1)
            {
                Host = IPAddress.Parse(ipAddress);
                var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.ReuseAddress, true);
                IPEndPoint localEndPoint = new IPEndPoint(Host, port);

                socket.Bind(localEndPoint);
                socket.Listen(backlog);
                return socket;
            }

and i have reverted the code so its the original code from the homeosgadgeteerlibrary


//...
try
                    {
                        // process incoming request
                       
                        clientSocket = LocalServer.Accept();
                     
                        Debug.Print("Got a connection!");

                        clientSocket.ReceiveTimeout = Timeout;
                        clientSocket.SendTimeout = Timeout;
                        // parse message an create an object containing parsed data 
                        responder = new Responder();
                        responder.ClientEndpoint = clientSocket.RemoteEndPoint.ToString();
                        responder.ClientSocket = clientSocket;

                        Debug.Print("Accepted connection from " + responder.ClientEndpoint);

                        Debug.Print("Thread: " + Thread.CurrentThread.ManagedThreadId + " accepted a socket!");
                        Thread t = new Thread(new ThreadStart(ProcessRequest));
                        t.Start();
                        newThread = true;
                    }
                    catch
                    {
                        if (clientSocket != null)
                        {
                            try
                            {
                                clientSocket.Close();
                            }
                            catch
                            {
                                
                            }
                 }
                    }
//...

2nd: I make requests from the browser and from the homeos platform so the socket is not waiting for work but rather stuck in some kind of exception.

3rd: I now have a try catch around the accept method

some new questions:

a) Im using the enc28 ethernet module could there be a problem with this device?
b) can there be multiple server sockets? since i have another socket with udp running. which posts beacons every once in a while.

a) I use ENC28 too, with G120
b) yes, the socket Limit is somewhere around 32. Multiple ingoing and outging Connections with TCP and/or UDP are no Problem.

Hi

Thanks for your help it turned out to be a problem with the implementation of the Library.

ClientSockets weren’t closed correctly…

Another problem was that in the library they used a flag to determine if the message was sent and they set the flag true before the message actually was sent…