in reply to Using Threads For Simple SMTP Relay Server

Not having your modified Client3 code, I substituted Net::SMTP::Server::Client2, and your code seems to work just fine. Here is a clip of the telnet session:

220 Debatable SMTP 0.2 Ready. HELO 250 OK Welcome HELO 250 OK Welcome DATA 503 start with 'mail from: ...' HELP 214-Commands 214-DATA EXPN HELO HELP MAIL 214 NOOP QUIT RCPT RSET VRFY NOOP 250 Whatever. RSET 250 buffahs ah cleah, suh! VRFY 252 Nice try. EXPN 252 Nice try. MAIL 501 could not find name@postoffice in <> RCPT 553 no user@host addresses found in <> QUIT 221 Ciao

And the associated console trace:

C:\test>647478 Launched Thread Number 1 Use of uninitialized value in numeric eq (==) at C:\test\647478.pl lin +e 58. Client Processing Started GOT IN HERE 1172 command: HELO 1172 command: HELO 1172 command: DATA 1172 command: HELP 1172 command: NOOP 1172 command: RSET 1172 command: VRFY 1172 command: EXPN 1172 command: MAIL 1172 command: RCPT 1172 command: QUIT Client Processing Finished

So, apart from not having any mail or users to retrieve, everything seems to work as designed. It suggests that your modifications to produce Client3 are probably at fault. My best suggestion is that you return to Client2 and then add back your modifications step by step to see what causes the breakage.


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
"Too many [] have been sedated by an oppressive environment of political correctness and risk aversion."

Replies are listed 'Best First'.
Re^2: Using Threads For Simple SMTP Relay Server
by lamberms (Sexton) on Oct 29, 2007 at 12:18 UTC
    Thanks. I'll give that a try.
Re^2: Using Threads For Simple SMTP Relay Server
by lamberms (Sexton) on Oct 29, 2007 at 13:33 UTC
    Using Client2 yields the same result. It looks as if the integer handle for the socket is not working.
Re^2: Using Threads For Simple SMTP Relay Server
by lamberms (Sexton) on Oct 29, 2007 at 17:19 UTC
    It looks like ActiveState perl strikes again. Before I start reading from the IO::Socket in the Client3 I can write to it. Once I start reading from it in Client3::get_message() what I write to the socket is never sent to the other side of the socket. I guess it is blocking.
      It looks like ActiveState perl strikes again.

      That strange, because I'm using ActiveState Perl also.

      I guess it is blocking.

      Sockets are blocking by default and nothing in the code you posted attempts to set them as non-blocking.

      Before I start reading from the IO::Socket in the Client3 I can write to it. Once I start reading from it in Client3::get_message() what I write to the socket is never sent to the other side of the socket.

      You cannot simultaneously read and write to a blocking socket. It's like using a walky-talky. There is no point in talking whilst the person on the other end is transmiting, because they will not hear you.

      But I don't see the need for a non-blocking socket for implementing the SMTP protocol?

      It is a command-response protocol. Your client3 code should work in the same way as the Client2 code. Wait for a command, and once you get one, make no more reads until it has finshed sending the complete response to that command.


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
        I used a poor choice of words. Blocking isn't right. What I meant to say was that once I start reading from the socket (one line at a time) I can't write to it and have it received. I have switched back to the Client2 code. The offending portion is in get_message(). If I run with the following code:

        # sub process { sub get_message { my $self = shift; my($cmd, @args); my $sock = $self->{SOCK}; $self->_reset0; print $sock "STUFF1\r\n"; while(<$sock>) { print $sock "STUFF2\r\n"; print "$$ command: $_"; ... rest of routine

        The output (from the perspective of the client is:

        Net::SMTP>>> Net::SMTP(2.31) Net::SMTP>>> Net::Cmd(2.29) Net::SMTP>>> Exporter(5.60) Net::SMTP>>> IO::Socket::INET(1.31) Net::SMTP>>> IO::Socket(1.30) Net::SMTP>>> IO::Handle(1.27) Net::SMTP=GLOB(0x20f758c)<<< 220 Debatable SMTP 0.2 Ready. Net::SMTP=GLOB(0x20f758c)>>> EHLO localhost.localdomain Net::SMTP=GLOB(0x20f758c)<<< STUFF1

        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.