Photon simple telnet to serial fails

What would you suggest @mdma?

What about a readUntil* or something?

@mdma, if there is no indication from WICED (which I find insanely odd), then the documentation for connected() needs to be changed. There has to be a way!

I just discovered the very same issue. My test code looked almost identical to @peekay123ā€™s.

I also agree that if the WICED does not provided any indication of a TCP close from the remote side it is insanely odd.

@pilottrack, though there is no client connection closed detection, I ended up using a timeout coupled with the server.close() function that @mdma added (in the beta develop branch) allowing me to close an open Server socket.

It turns out that detecting a closed client-side connection is not so obvious. Unless you attempt a transaction and it fails, thus indicating a closed connection, how else are you supposed to detect closure? There are no ICMP type management taking place so user code has to do that. :smile:

1 Like

Might be useful to use Wireshark and monitor the telnet socket close from Putty et al and see whether it is sending the FIN to the proton. If it isnā€™t, the socket isnā€™t been closed on the client properly. If it is, its a bug in WICED I would think.

Above image compliments of IBM

Does this also happen with a core as well. I know both the CC3000 and CC3200 TCP stacks handle client socket closes correctly. Testing with a core might help isolate whether its WICED or the terminal application at fault.

3 Likes

@peekay123, I was about to implement something similar to the above (user code determining when to close the session). It was about then I found this thread.

If I get some time later this afternoon I was going to try to see if .read() on a closed connection will unset the .connected() flag.

Yes, the normal method to determine that the remote connection has closed the socket is to do a recv() on the socket. If select() indicates the socket has data available and recv returns negative or 0 as the status, the socket has been closed remotely.

@pilottrack, using .read() will not work since it only looks at the receive buffer pointers. :cry:

a flush() then a read() will do the job :wink:

@mdma, so doing a flush() and then a read() will cause .connected() to go false if the connection has been lost?

I have managed to get a reliable TCP connection going from my PC to the Photon over WiFi. :smile:

When I close the connection from my PC I get the dual sequence of FIN/ACK,ACK,FIN/ACK,ACK as per the image posted by @pra above.

I have also implemented flush/read suggested by @mdma above. Should this on its own force ā€˜client.connected()ā€™ to return false on the Photon, if the connection is actually closed?

However, in my case the Photon seems to continue behaving as if the connection is still active(ā€˜client.connected()ā€™ returning true), when it has been confirmed as closed (via wireshark).

My question is: Is this a known bug & if so I am OK waiting fora solution, as its easy to recover by resetting the Photon. If not, what is the best way to determine on the Photon if the TCP connection is already closed by the remote PC.

:information_source: FYI: I am sending 100+ pieces of data back (circa 1K bytes) to the PC over WiFi every time an IR signal is detected by the Photon. Combining all this text into a single buffer before sending seemed to improve reliability a lot. when I wasnā€™t buffering, it looked like the Photon was sending 2 or 3 packets each time and there seemed to be more retransmits happening.

ā€¦fortunately, RAM on the Photon is more than enough for this project. :+1:

Thanks for the details and for trying out the proposed fixed. This is a known bug and we are actively investigating it. Iā€™ll keep you posted!

What status did the read(0 after the flush() return. Again, Iā€™m not sure what the wiring API is doing here, but the remote socket close process using Berkeley Sockets is:

  1. Check whether socket has information vis select() (available() I think in wiring)
  2. If yes, do a recv() (flush/read with wiring ?)
  3. if recv() returns 0 or negative, then the remote socket is closed otherwise process the received data
  4. close the local socket (disconnect())

It works for me on other systems but I always use sockets directly

Seems to be the same when connected and disconnected

client.connected() :1
flush/read -1
4294960287

I get the same debug info above when its actually connected and when it is disconnected. That is:

Client.connected always returns 1 - even when disconnected (via wireshark).

The flush/read sequence returns -1 for read(), in both scenarios

The large number (= -7009) is always returned from client.print - even when actually disconnected, regardless of different size payloads (varies from 592 to 899 actually sent). It is supposed to return the number of bytes sent (?)

...from docs
Returns:  byte:  print() will return the number of bytes written, though reading that number is optional

ā€¦possibly a bug(?)

Hope this helps a little. Unfortunately, I am going offline now and will park this activity pending a resolution by the Particle team.

(just to be clear, I am using a direct TCP connection over WiFi from a .Net Windows application - not Telnet)

Iā€™ve pushed a fix for this to the develop branch. Please try it out and let me know! :smile:

2 Likes

Is TCPServer.close() going to be part of the 0.4.x firmware for the Core as well?

Yes, most of the firmware is common for both the Core and the Photon so single improvements happen on both platforms.

1 Like

Iā€™m still having issues with TCPClient.connected() on 0.4.4 returning true even though the server has closed the connection. I tried doing a client.flush() and client.read() to get it to know that the connection has been closed but still no luck.

I should say that in my case Iā€™m using a client that was created using client.connect(ā€¦) and the server is closing the connection.