arduino / YunBridge

72 stars 32 forks source link

Connection reset by peer #28

Open cldavid opened 8 years ago

cldavid commented 8 years ago

I've a php webpage that does the following.

When I open my website in multiple tabs, continuously refreshing the page. Will break the bridge socketserver with errno 131. Bridge.py is unable to automatically recover from this error

Traceback (most recent call last):
  File "bridge.py", line 87, in <module>
    res = pr.process()
  File "/usr/lib/python2.7/bridge/packet.py", line 123, in process
    self.processor.run()
  File "bridge.py", line 49, in run
    runner.run()
  File "/usr/lib/python2.7/bridge/console.py", line 60, in run
    self.socket_receive(sock)
  File "/usr/lib/python2.7/bridge/console.py", line 78, in socket_receive
    chunk = client.recv(1024)
socket.error: [Errno 131] Connection reset by peer
facchinm commented 8 years ago

Hi @cldavid , which version of Yun distribution are you using? Can you also post the sketch so we can reproduce the bug? Thanks

cldavid commented 8 years ago

Sketch: https://github.com/cldavid/ds_motor.git Branch: arduino-yun

PHP Webpage https://github.com/cldavid/aquacc/tree/master/www

What is the easiest way to check the version number. I believe I'm running OpenWRT Luci.

If you want I can try to compile my sketch with the latest version of the bridge library and upgrade the YunBridge scripts with the latest version coming from the git repo.

pbudzon commented 7 years ago

Hi,

I'm running Yun shield with Arduino UNO and getting the same error. I'm not using PHP, but simply running telnet localhost 6571 on Yun shield. If I do ctrl+c I get

Console escape. Commands are:

 l  go to line mode
 c  go to character mode
 z  suspend telnet
 e  exit telnet

pressing e seems to exit telnet and most of the time the bridge dies as well (not always). The contents of /tmp/bridge.py-stderr.log:

Traceback (most recent call last):
  File "bridge.py", line 90, in <module>
    res = pr.process()
  File "/usr/lib/python2.7/bridge/packet.py", line 123, in process
    self.processor.run()
  File "bridge.py", line 49, in run
    runner.run()
  File "/usr/lib/python2.7/bridge/console.py", line 60, in run
    self.socket_receive(sock)
  File "/usr/lib/python2.7/bridge/console.py", line 78, in socket_receive
    chunk = client.recv(1024)
socket.error: [Errno 131] Connection reset by peer

Re-running /usr/bin/run-bridge doesn't seem to work - it restarts the bridge.py but the communication from Arduino's side does not restore. The only way to make it work again is to plug the power out and back in to restart the underlying Arduino (remember, I'm running the Yun shield on top of Arduino Uno).

I'm running the latest Yun from https://www.arduino.cc/en/Main/Software (1.6.2).

facchinm commented 7 years ago

Hi @pbudzon and @cldavid , from the reports I believe that closing any socket could kills the bridge if the timings are "wrong". The sockets_to_read_from list is updated too late and the closed socket is still there, so the read fails badly. Probably catching the exception generated by https://github.com/arduino/YunBridge/blob/master/bridge/console.py#L78 when one of the sockets gets closed could solve the issue. I tested the telnet method but was never able to kill it. Could you retest after trapping the exception (like this http://stackoverflow.com/questions/20568216/python-handling-socket-error-errno-104-connection-reset-by-peer?answertab=votes#tab-top) ? Thanks!

pbudzon commented 7 years ago

Hi @facchinm,

Thanks for that. The problem is tricky, as it seems to be a race condition if I understand correctly, so it's not easy to reproduce. I managed to cause it again using telnet after a couple of tries.

I have replaced line 78 in console.py with the following:

        chunk = ''
        try:
            chunk = client.recv(1024)
        except SocketError as e:
            if e.errno != errno.ECONNRESET:
                raise
            pass

And so far I have no been able to cause the error again, so it seems like it may be working!

Would you like me to submit that change as a pull request?

facchinm commented 7 years ago

A PR (with a clear description on how to trigger the race condition) would be great! Thank you so much!

shreyansh96 commented 5 years ago

Replication sequence: Connect any client to the socket server and close it abruptly without using socket.close() after sending some commands (ctrl + z can be used). Solution: On the server end port forward the port on which the server is started to any other port and use this port on the client side to connect. This will solve the issue. For ex: you can use socat library to port forward - (socat TCP-LISTEN:8888,fork TCP:127.0.0.1:6571) &