SMTP Mail: "Socket was closed" InvalidOperationException

+1 vote
asked Feb 10, 2016 by mrblint (340 points)

After testing for IsConnected (port 465) and IsAuthenticated (SmtpAuthentication.Login), I invoke the Send method.

An InvalidOperationException is raised. "Socket is closed".

What causes the socket to close?

Applies to: Rebex Secure Mail

1 Answer

0 votes
answered Feb 11, 2016 by Tomas Knopp (58,560 points)
edited Mar 14, 2016 by Tomas Knopp
 
Best answer

Actually, the IsConnected or IsAuthenticated property have only informative purpose, they do not actively check the connection.

So you would need your own method to check whether the connection is still alive. The best is to send a NOOP command to the server and get a response.

In fact, even with this approach it can happen, that your method returns 'true' and in the next moment the socket could be potentially closed.

Due to the nature of TCP/IP, the socket can be closed by either the SMTP server, or by some network device along the way without the client being notified, so be prepared for the InvalidOperationException even though you actively check the connection state before the Smtp.Send method. Although this would be really really small probability.

commented Feb 22, 2016 by mrblint (340 points)
Thanks Tomas for this helpful explanation.
commented Mar 14, 2016 by Tomas Knopp (58,560 points)
A short code snippet for this:

        bool IsConnected(Smtp smtp)
        {
            smtp.SendCommand("NOOP");
            SmtpResponse response = smtp.ReadResponse();

            if (response.Group != 2)
                return false;

            return true;
        }

        bool IsAuthenticated(Smtp smtp)
        {
            if (!IsConnected(smtp))
                return false;

            return smtp.IsAuthenticated;
        }

            Smtp smtp = new Smtp();
            smtp.Connect("smtp.gmail.com", SslMode.Implicit);

            Console.WriteLine(IsConnected(smtp));
            Console.WriteLine(IsAuthenticated(smtp));

            smtp.Login("user", "pass");

            Console.WriteLine(IsAuthenticated(smtp));

            smtp.Disconnect();

            Console.WriteLine(IsConnected(smtp));
            Console.WriteLine(IsAuthenticated(smtp));
...