Ok, I will just sum it all up and add one more option:
1) Generally, in your 4th step, if the connection is not alive, your send() will return an error. (Note: your connection can remain active indefinitely, even if you send no traffic into it).
2) If you've opened the socket with a keep-alive option, TCP will automatically send a heartbeat message to monitor the connection and close it if it is not alive. From memory, keep-alive is a default option with Winsock and most UNIX/Linux implementations.
3) The other option which I use a fair bit is to send my own hearbeat packet into connection (both ways). This also has the advantage that intermediate devices such as routers don't try to be too smart and drop the connection as inactive - as it always has some (small) traffic.
4) And finally, to check for connection being alive, you can use recv with MSG_PEEK option, something like:
char data;
recv(socket,&data,1, MSG_PEEK);
but make sure you are in non-blocking mode. (Note - using PEEK makes sure that the received data is not de-queued and can be read/processed by proper receive routine). This is the method used by Ulimiate TCP/IP.