Crash and Burn with TCPSocket.

30 Oct 2019

I have an application that uses a number of IP sockets including a server. Having got fed up with being nagged that TCPServer was depreciated every time I compiled my code, I decided to update using TCPSocket as mandated by the latest OS updates. TCPServer works well, is stable and reliable so I assumed TCPSocket would work the same way, but oh how wrong I was!

In typical MBED style, documentation on how to use TCPServer is utterly pitiful and examples completely non-existent, so I thought it may be useful for others to see the challenges I’ve found so they don’t need to waste the hours of their lives that I’ll certainly never see again, and also in the hope that MBED may be tempted to improve TCPServer by adding some basic error detection. Hopefully the team will also be shamed into improving the documentation, but I won’t hold my breath.

I’m using various IPsockets on the same thread and so ‘blocking’ is set to 0.

1) Accepting connections: On the old TCP Server if a connection was made to the server, it simply dropped any existing connection and accepted the new one. Very useful for killing errored connections and preventing multiple parallel connections. With TCPSocket Once a connection is accepted using:

TCPSocket *MyServerSocket; MyServerSocket = sock.accept(&Error);

If another connection is made, the OS will crash!

2) Closing: Connections are closed using MyServerSocket ->close(); OK so far, but if you accidentally try and close a socket that’s already been closed then, the OS will crash!

3) Sending data: Sending data to an active socket using:

MyServerSocket ->send(out_buffer, sizeof(out_buffer));

Works great, but if the socket has disconnected for some reason, guess what happens? Yes, the OS will crash!

4) As there is nothing in the API to test if there is a connection or not, I tried using If (MyServerSocket) to see if I had a valid pointer to a socket. What I then found is that following MyServerSocket ->close(); MyServerSocket still points to something so If (MyServerSocket) returns true. I’ve managed to get round this by explicitly setting MyServerSocket to NULL when I close the socket.

So in summary, TCPSocket lacks the most basic error checking which was inherent in TCPServer which means it is very easy to crash MBED with any minor error. These challenges can be overcome, but it does seem retrograde step to have to write loads of extra code, when TCPServer worked perfectly in the first place, especially when it took me a week of testing to work out what was going on.

08 Nov 2019

Hi Roger,

We really appreciate that you give us these invaluable feedback, this is really helpful for everyone.

Mbed OS is trying to provide an easy-to-use interface and easy-to-read documentation, to make every beginner enjoy using Mbed OS, from this post, the expectation looks still far away, even though we are dedicated to make it better. So, we are very welcome all developers to contribute their thoughts and skills, to stay with us, to make Mbed OS better, and we really thank that.

I am sure you are already know our project on GitHub, https://github.com/ARMmbed/mbed-os, you can raise an issue with detail log and reproduce instruction, or even better to send us a PR, we would be most grateful.

Regards, Desmond

04 Dec 2019

I'm working also on changing some server code from TCPServer to TCPSocket. The TCPSocket was a proprietary Mbed invention, now a more standardardized Berkley socket API is used. There the socket state is not monitored, so it looks like a Client and a Server class is necessary for convenience, but this is not standard. The sockets stats feature keeps track of the status, but I guess this has a performance impact and is also not standard when working with sockets. I've seen also some differences, this is notable: https://github.com/ARMmbed/mbed-os/blob/9248169f1f008a6550cbf725f9d5c91e68c28f3c/features/netsocket/InternetSocket.cpp#L94-97

Such breaking code changes should come with updated examples. There is only a client example, none for a server. The https://os.mbed.com/teams/sandbox/code/http-webserver-example/ is also not working with actual mbed-os, the easy connect stuff is confusing because a lot has changed.