Yes, that is what "gracefully" means. Another way could be to keep a separate connection with another socket over which you send control information ("file transfer started", "file transfer complete", "file transfer aborted" and so on).
Also, ungracefully closing a TCP connection is not inherently bad, it's only bad in that you may lose buffered data or data in transit that, from the application's perspective, has already been sent (unless the application implements its own acknowledgment protocol on top of TCP). If you're aborting a transfer, you presumably no longer care if the file arrives intact, so it's okay. Just make sure the remote can distinguish between a completed transfer and a prematurely aborted transfer, and make sure the socket is not used for anything else.