The reason the sleeps are needed is that SMTP is "conversational". After the server receives a line, it replies with something. The client replies, and the server replies. However, TCP doesn't care about the content. (Of special importance here is the line breaks.) TCP gets a stream of data and a destination. It chops off a negotiated (at a lower level than your application so this is out of your control) number of octets of data and sends them. And repeat until done.
The problem is that when the server receives a TCP segment that has the linebreak, odds are (negotiated_octet_count to 1) that some amount of the next line is going to be included. At which point the server says, "You are not letting me speak, so this is not a conversation, and we are not going to continue."
So, that is why your first attempt failed. The reason your 2nd attempt succeeded is that netcat doesn't require that every TCP segment be full. It works on streams, not files. So netcat doesn't work upto EOF. It works until stdin closes (or timeout is reached if you specify one). And when the stdin "delays", it sends what it has. This ensures that your server gets a TCP segment that ends in a line break. You will probably find that your server can handle a much smaller than 1 second sleep. I us .05, but you might want to use .1 to give it some safety.
I gave an example here but I'm going to repeat it because your quoting is very irregular to me.
$ cat email_msg.txt
HELO localhost
MAIL FROM:<[email protected]>
RCPT TO:<[email protected]>
DATA
From: [IES] <[email protected]>
To: <[email protected]>
Date: Fri, 27 Oct 2017 06:14:11 +0000
Subject: Test Message
Hi there! This is supposed to be a real email...
Have a good day!
-- System
.
QUIT
$ function slowcat(){ cat "$1" | while read; do sleep .05; echo "$REPLY"; done; }
$ slowcat email_msg.txt | nc localhost 25
220 et3 ESMTP Exim 4.89 Fri, 27 Oct 2017 06:18:14 +0000
250 et3 Hello localhost [::1]
250 OK
250 Accepted
354 Enter message, ending with "." on a line by itself
250 OK id=1e7xyA-0000m6-VR
221 et3 closing connection
smtp() { cat "$1" |while read; do sleep .05; echo "$REPLY"; done |nc "${2:-localhost}" "${3:-25}"; }
. This will default to localhost on port 25 but can be changed. Syntax issmtp FILE [server [port]]
– Patricapatrice