Main Site Documentation

Socket problem between Fez Cobra and EMX Development system


#1

When we setup a socket server on one of the two boards and a client on the other, we notice that the connect() works, but after some bytes are sent, nothing is received at the server side (buffer empty).

The strange thing is: If we try this using the emulator on a pc, everything works fine.

We initialize the network using:


            foreach (Microsoft.SPOT.Net.NetworkInformation.NetworkInterface iface in
                Microsoft.SPOT.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces())
            {
                iface.EnableStaticIP("192.168.0.11", "255.255.255.0", "192.168.0.1");
            }

...

  using (Socket serverSocket = ConnectSocket(server, port))
            {
                // Send request to the server.

                Byte[] bytesToSend = Encoding.UTF8.GetBytes("some text");
                serverSocket.Send(bytesToSend, bytesToSend.Length, 0);
}

...

private static Socket ConnectSocket(String server, Int32 port)
        {
            // Get server's IP address.
            IPHostEntry hostEntry = Dns.GetHostEntry(server);

            // Create socket and connect to the server's IP address and port
            Socket socket = new Socket(AddressFamily.InterNetwork,
                SocketType.Stream, ProtocolType.Tcp);
            socket.Connect(new IPEndPoint(hostEntry.AddressList[0], port));
            return socket;
        }

We use the example from the SDK 4.1 Samples.

Server code:


const Int32 c_port = 12000;

            // Create a socket, bind it to the server's port, and listen for client 
            // connections.
            Socket server = new Socket(AddressFamily.InterNetwork,
                SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, c_port);
            server.Bind(localEndPoint);
            server.Listen(Int32.MaxValue);
            

            while (true)
            {
                // Wait for a client to connect.
                Socket clientSocket = server.Accept();

                // Process the client request.  true means asynchronous.
                new ProcessClientRequest(clientSocket, true);
            }

...

/// <summary>
    /// Processes a client request.
    /// </summary>
    internal sealed class ProcessClientRequest
    {
        private Socket m_clientSocket;

        /// <summary>
        /// The constructor calls another method to handle the request, but can 
        /// optionally do so in a new thread.
        /// </summary>
        /// <param name="clientSocket"></param>
        /// <param name="asynchronously"></param>
        public ProcessClientRequest(Socket clientSocket, Boolean asynchronously)
        {
            m_clientSocket = clientSocket;

            if (asynchronously)
                // Spawn a new thread to handle the request.
                new Thread(ProcessRequest).Start();
            else ProcessRequest();
        }

        /// <summary>
        /// Processes the request.
        /// </summary>
        private void ProcessRequest()
        {
            const Int32 c_microsecondsPerSecond = 1000000;

            // 'using' ensures that the client's socket gets closed.
            using (m_clientSocket)
            {
                // Wait for the client request to start to arrive.
                Byte[] buffer = new Byte[1024];
                if (m_clientSocket.Poll(5 * c_microsecondsPerSecond,
                    SelectMode.SelectRead))
                {
                    // If 0 bytes in buffer, then the connection has been closed, 
                    // reset, or terminated.
                    if (m_clientSocket.Available == 0)
                        return;

                    // Read the first chunk of the request (we don't actually do 
                    // anything with it).
                    Int32 bytesRead = m_clientSocket.Receive(buffer,
                        m_clientSocket.Available, SocketFlags.None);

                    // Return a static HTML document to the client.
                    String s =
                        "HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n<html><head><title>.NET Micro Framework Web Server</title></head>" +
                       "<body><bold><a href=\"http://www.microsoft.com/netmf/\">Learn more about the .NET Micro Framework by clicking here</a></bold></body></html>";
                    m_clientSocket.Send(Encoding.UTF8.GetBytes(s));
                }
            }
        }

The if statement:
if (m_clientSocket.Poll(5 * c_microsecondsPerSecond, SelectMode.SelectRead))

is never true…

Any idea what the problem could be?


#2
using (Socket serverSocket = ConnectSocket(server, port))
            {
                // Send request to the server.
 
                Byte[] bytesToSend = Encoding.UTF8.GetBytes("some text");
                serverSocket.Send(bytesToSend, bytesToSend.Length, 0);
}

This snippet will get a socket from ConnectSocket, and then send some bytes. Immediately after the data is sent, the serverSocket object goes out of scope. If could be GC’d before the data is actually sent.

You want to close the socket after the send, making sure that the data is sent. For a quick test, put a Thread.Sleep(1000) after the send.


#3

Unfortunately the Sleep() does not help. I break with the debugger after the sleep and still the socket has 0 bytes available. The connect works, but nothing is sent over the socket.


#4

After spending way too much time on this, the solution is found! All boards have the same MAC address. If we change the MAC address of one of the boards, everything functions as designed…


#5

Glad you found the problem and it worked out for you.