1 2 Previous Next 28 Replies Latest reply on Aug 31, 2015 1:24 PM by AlexT_Intel

    Ethernet Library: sketch crashes when remote client closes connection

    Fab64

      I have written a simple server which receives and sends data to a client (code below).

       

      Everything works until the remote client closes the connection: the sketch crashes and stops working.

       

      The same code runs on Arduino without any issue.

       

      This looks like a bug.

       

      Has anyone experienced the same issue ? Any suggestion ?

       

      --------------------------------------

       

      void loop() {

       

        EthernetClient client = server.available();

       

        Serial.println("Waiting for client ");

       

        if (client) {

       

          Serial.println("new client");

       

          while (client.connected()) {

          

            int n=0;

          

            Serial.println("\tClient connected");

       

            if (client.available()) {

       

              char c = client.read();

              Serial.write(c);

            }

            Serial.println("");

       

            client.write((unsigned char *)"Hetllo",5);

          }

       

          delay(1);

          client.stop();

          client = NULL;

       

          Serial.println("Client disconnected");

        }

       

        delay(1);

      }

        • 1. Re: Ethernet Library: sketch crashes when remote client closes connection
          arduino_4_life

          Sorry nobody's answered you yet- I'm working on finding somebody who knows hang in there!

          • 2. Re: Ethernet Library: sketch crashes when remote client closes connection
            arduino_4_life

            Can you post all of your steps exactly as you did them, and I'll try and recreate your problem here?

            then we can go from there

            Erik

            • 3. Re: Ethernet Library: sketch crashes when remote client closes connection
              Fab64

              Hi Erik,

               

              thank you for helping me.

               

              The steps to reproduce the problem are quite simple:

               

              1) run the sketch on Galileo

              2) connect to Galileo from a client which opens a socket

              3) read and write some data from the client

              4) close the socket on the client

               

              At this point, the sketch crashes.

               

              Let me know if you need more information.

              • 4. Re: Ethernet Library: sketch crashes when remote client closes connection
                MattRichardson

                I'm curious, can you describe how you know that the sketch has crashed?

                 

                I might be encountering the same issue, but I think it has to do with the fact that client.connected() doesn't evaluate as false when the remote host disconnects. I sprinkled in some debug statements and I don't see any kind of crashing (not sure what that would look like anyway).

                • 5. Re: Ethernet Library: sketch crashes when remote client closes connection
                  arduino_4_life

                  Yeah, I'll need a bit more info than that...

                   

                  "2) connect to Galileo from a client which opens a socket"

                   

                  Please post all of the arduino code (and any other code) that you used, including any shell commands or additional scripts.

                   

                  I want to set the up the same scenario that you had.

                  • 6. Re: Ethernet Library: sketch crashes when remote client closes connection
                    Fab64

                    I have attached the test sketch I am using on Galileo.

                     

                    The client is a complex iOS application so it's not easy to show you the exact code. However, I have created a simple c socket client which reproduces exactly the same problem.

                     

                    When the socket closes the Galileo console shows

                     

                    ** B0100000063f694

                     

                    the sketch stops and no more connections are accepted.

                     

                    Thank you for trying to help me.

                    • 7. Re: Ethernet Library: sketch crashes when remote client closes connection
                      AlexT_Intel

                      Hi Fab64,

                       

                      Have you solved this problem since then? I have not that much experience with Arduino programming yet :-) but I might be able to take a look at this sometime on the upcoming weekend, if that's still actual.

                      • 8. Re: Ethernet Library: sketch crashes when remote client closes connection
                        byron

                        I have the same issue. Using the bundled web server example and after a reboot, I am able to access the web page 3-4 times before the sketch crashes and get the ** B0100000063f694 message. Afterwards, only a reboot of the entire board can fix the problem. Resetting the sketch, changing ips, etc, occasionally lets me view a page, but it is very unreliable.

                        • 9. Re: Ethernet Library: sketch crashes when remote client closes connection
                          AlexT_Intel

                          I'll see if I can help here, will take a look over the weekend.

                          • 10. Re: Ethernet Library: sketch crashes when remote client closes connection
                            AlexT_Intel

                            Ok, so I know the reason, but I only hava a partial fix. Look for fix below if you aren't interested in details, but they're worth readin as there are some deviations from what you'd expect.

                             

                            I would say this needs Galileo developers' attention as the connected() method in EthernetClient.cpp doesn't really work as one would expect. I've spent about a day trying to find an elegant solution, but wasn't able to do that without reworking a lot of it and I'm not that interested in doing that :-) so I'll present what I've found out and have them decide if they read this.

                             

                            The immediate reason for crash is that Galileo uses Linux send() function without any additional flags set for implementing EthernetClient::write() and that causes SIGPIPE signal when the other end of the socket is closed (see man). And SIGPIPE in turn kills the sketch process in an unexpected way.

                             

                            The fix for that is either adding

                            #include <signal.h>
                            setup() {
                                 signal(SIGPIPE, SIG_IGN);
                            }
                            

                            to your sketch

                             

                            or (IMHO better)

                             

                            replacing the if on line 161 of arduino-1.5.3\hardware\arduino\x86\libraries\Ethernet\EthernetClient.cpp:

                            if (send(_sock, buf, size, 0) < 0) {
                            

                             

                            with

                             

                            if (send(_sock, buf, size, MSG_NOSIGNAL) < 0) {
                            

                             

                            That won't make the sketch work as you'd expect it to, but it will stop it from crashing.

                             

                            The next problem is that EthernetClient::connected() doesn't really detect the situation when client disconnects. The method doesn't check the connection per se, but relies on a variable, which only gets set after explicitly calling EthernetClient::stop(), and that ruins all the example sketch logic - it starts to write the data to the disconnected client in a loop. Without that signal fix it was just crashing right on the first write to the closed socket after getting SIGPIPE.

                             

                            The only way of fixing that I could come up with given the current code without somehow reworking a lot of it was adding the explicit client connection drop in response to any send errors.

                             

                            The [almost] full fix replaces some code in the abovementioned if, so that the final version of it (including the above signal fix) looks like that:

                            if (send(_sock, buf, size, MSG_NOSIGNAL) < 0) {
                                trace_error("%s unable to send on sock %d errno %d, dropping the connection", __func__, _sock, errno);
                                // FIXME: If we just set it to -1 here, then e.g. stop() will not work on a socket,
                                // where the other side dropped the connection and the connected() method will still be returning trus.
                                // Thus replacing it with stop(), which is still not the best solution, but covers the most cases.
                                // Maybe we'd want to do that based on errno rather then stop() for all errors.
                                // What apparently would be helpful here is the always actual socket status, like on Arduino.
                                //_sock = -1;
                                stop();
                                return 0;
                            }
                            

                             

                            The comment is of course not mandatory, but will help you to understand what's going on if you later would want to adjust that stop() logic.

                             

                            Now both demonstration sketches in this thread work mostly fine for me. One thing to note is that even with this fix the broken pipe (when client properly closed a connection with close()) will be detected only after the second send() after closure, that's expected Linux/TCP behavior (see FAQ 2.1 or Google, there are a lot of articles on that).

                             

                            Hope this helps. That was a lot of text, I know :-)

                            • 11. Re: Ethernet Library: sketch crashes when remote client closes connection
                              byron

                              Alex.

                               

                              I really appreciate your work on this issue and hopefully it gets fixed.

                               

                              However, for me, this is just another nail in the Galileo's coffin. If I wanted to use Linux I would just pull out one of my Raspberry Pi's. I hope the community pushes Intel to make a platform that is actually usable as an Arduino replacement, but it feels like they released this one too soon. On to SparkCore!

                               

                              Thanks,

                              Byron

                              • 12. Re: Ethernet Library: sketch crashes when remote client closes connection
                                AlexT_Intel

                                You're welcome, digging that deep was actually fun! :-)

                                 

                                I think it will get better over time, after these initial quirks are ironed out. IMHO there's actually a place under the Sun for such combination of Linux and Arduino compatibility, I personally find it interesting to be able to mix typical UNIX code with Arduino one and have access to those microcontroller-like I/O capabiltities at the same time as the typical PC interfaces like mPCEe and USB and Ethernet without additional shields.

                                • 13. Re: Ethernet Library: sketch crashes when remote client closes connection
                                  RSavage1

                                  Hi Alex,

                                  Thanks for the fix on this one. I was also having the same problem in that I was using Galileo as a web server and intermittently the web server program would crash (i.e. with IDE serial window open I would get ** B0100000063f694). The crash would occur sometimes when a web browser client asked for a page refresh from the server. I was going crazy trying to troubleshoot this and then I found your post. I followed the instructions and added the following to my sketch and now everything works great with no crashes.

                                   

                                  1. Add #include <signal.h> at the start of the sketch

                                  2. Under "void setup()" added signal(SIGPIP,SIG_IGN);

                                   

                                  Thanks

                                  1 of 1 people found this helpful
                                  • 14. Re: Ethernet Library: sketch crashes when remote client closes connection
                                    AlexT_Intel

                                    That's cool, glad it helped and thanks for reporting that back! :-)

                                    1 2 Previous Next