I was unit testing SimpleSmtpServer in VS2008 / .NET 3.51 and noticed a socket related bug. Specifically, there is a deadlock bug between the listener thread and the main thread (unit test client in my case). In HandleSmtpTransaction, the code will lock up once the SmtpState changes to QUIT. This is because no more data is available to read form the socket so the read attempt will block and cause a dead lock with the client thread that attempts to check the result of a SMTP send. The simple fix is to check for the SMTP quit state inside the While loop in HandleSmtpTransaction like so:
while (smtpState != SmtpState.CONNECT && smtpState != SmtpState.QUIT)
Also, it's considered bad practice to use lock(this), I changed the code to use an explicit / private locking object.