in reply to Re^4: Using Threads For Simple SMTP Relay Server
in thread Using Threads For Simple SMTP Relay Server
In other words it only writes to the client the first time (it never sends STUFF2 to the client). Once the socket is read from writes aren't happening in other words. It is perplexing.
It's not perplexing at all. Your modifications are breaking the well defined SMTP protocol. You should not be modifying the get_message() method. And you certainly should not be writing to the socket within the read loop. The get_message() method is intended to, and *must*, be called as an atomic operation in order that the rules governing the protocol will be maintained.
What is happening is that you are writing to the socket at inappropriate points within the protocol exchange. The client, which is expecting the server to follow those rules, is being sent data when it is not expecting it. That breaks the protocol and the whole exchange gets screwed up.
In order to make the changes you require, you should be leaving the Client2 get_message() method untouched and only modify the command handlers. You could do this by C&Ping the whole module and then modifying the individial command handler subroutines, ie. those subs whose addresses are stored in the dispatch table:
my %_cmds = ( DATA => \&_data, EXPN => \&_noway, HELO => \&_hello, HELP => \&_help, MAIL => \&_mail, NOOP => \&_noop, QUIT => \&_quit, RCPT => \&_receipt, RSET => \&_reset, VRFY => \&_noway );
Alternatively, you could write your Client3 module as a subclass of the Client2 code and override (just) those routines you need to modify, through inheritance.
Either way, the keys to that dispatch table are the only commands that the SMTP protocol understands and its values are the subroutines that will be invoked when a properly conformant command message is received from the client. And it is those routines that you should be modifying or overiding.
Obviously, there are some changes to the get_message() method that might be appropriate, like sending log messages to a system log handler rather than the console, but even that could be achieved through redirecting STDOUT in a subclass. In general, you should leave the existing read loop untouched.
|
|---|