Net::SMTP Unexpected EOF error

Posted on 2003-10-25
Last Modified: 2012-06-21
I've searched the net, and couldn't find anything about a problem I'm having with Net::SMTP.
Could you suggest something or direct me somewhere about this problem ?  Ultimately I'm looking to get it resolved.
I get the error at various parts of the SMTP conversation, either after $smtp->to or $stmp->dataend(), etc.
The logs are like this:
Net::SMTP=GLOB(0x80664e4)>>> .
Net::SMTP: Unexpected EOF on command channel at line 163
From what it looks like, remote server drops the connection unexpectedly, yet I may be wrong.  I want to be able to know when this happens, so I can deal with it in my script.

I tried if (undef($stmp)) die "EOF error again";
However, this doesn't do it.  Even though $smtp should NOT be defined anymore, it seems to still 'be there", and program skips right past it.  Hence the script continues on (much faster though, since it doesn't really send anymore), and tells me that ALL emails were sent, when in fact the script stopped sending emails after the EOF error.  The only way to find out where it really stopped sending is to go to the log, where I found that EOF error.  What I want to do is to automatically stop any and all processing when that error happens.  In other words, do something like throw () catch () exception handling and deal with it from there.  Or anything else that will do the job.

Is there a way to do that ?  

Question by:dennismv
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 3
  • 3
  • +1
LVL 18

Expert Comment

ID: 9620639
I thnk you may be able to test for it by looking at the return value from each call. They should return false or undef if they fail.
To put it in a try-catch style, wrap it in an eval and call each method as
$smtp->method() or die "Something descriptive";

Part of the descriptive message might be the returned status message: $smtp->code() or $smtp->message(). See the Net::Cmd doc for more details.

The eval will also take care of the instances where your $smtp object is undefined.
LVL 51

Expert Comment

ID: 9620864
could you please post relevant parts of your code (including the use and new statements)

Author Comment

ID: 9621995
thanks. .  I'm still testing it

code so far..
use Net::SMTP;  
use strict;

$smtp=Net::SMTP->new($server, Timeout => 15, Debug => 1);

$smtp->to( $mailto );
$smtp->data();       # Start the mail  

# headers  
$smtp->datasend("From:  $mailfrom\n");  
$smtp->datasend("To:  $mailto\n");
$smtp->datasend("Subject: $subject\n");  

# body.  
$smtp->dataend(); # Send the termination string  

What I did, I put "or last;" at the end of each $smtp command instead of "or die 'desc.message';", because I have the above in a while loop
I don't know if it works yet, haven't had any errors.  I'll test it some more to make sure it does work.

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!


Expert Comment

ID: 9622134

I would advise you to use "\r\n" instead of "\n" in $smtp->datasend() method.
Let me know if this solves your problem.

Also are you trying to send some attachments?
Let me know.



Author Comment

ID: 9622163
no, no attachments, thanks for \r\n, I'll put it in.
but why ?  I thought \r\n is for more Windows, while \n is for unix encoding.  what's the difference ?


LVL 51

Expert Comment

ID: 9622171
what is $server set too?
and you're missing a final
LVL 18

Expert Comment

ID: 9622209
don't worry about the newline differences. Officially the SMTP protocol (and many other protocols) specify \r\n as newline character, but Net::SMTP takes care of that for you. See the documentation of Net::Cmd:
"datasend ( DATA )
    Send data to the remote server, converting LF to CRLF."

What I tried to explain with wrapping the smtp conversation in an eval block is the following:

eval {
  $smtp->mail($from) or
    die "Error sending to $from: " . $smtp->code() . ' '. $smtp->message();

  $smtp->to($to) or
    die "Error sending to $to: " . $smtp->code() . ' '. $smtp->message();

  $smtp->data($data) or
    die "Error sending data $data: " . $smtp->code() . ' '. $smtp->message();

if($@) {
  print STDERR "Error sending mail: $@";

The eval{} is like a try{} block in Java. The 'die' statements correspond to throw. If a die gets triggered, it takes you out of the eval{} block, setting $@ to contain the message. So the if($@) is like the catch part.
This way you can continue your code and know when and why it failed.


Author Comment

ID: 9633864
this is just an update.  eval helped to kinda track down some problem areas, but I still get the error.  However, I am not yet stuck, as I still have things to try before I 'give up'.

Just so you know how it's going:
the log usually goes like this:
Net::SMTP=GLOB(0x82616e0)>>> MAIL FROM:<>
Net::SMTP=GLOB(0x82616e0)<<< 250 sender <> ok
Net::SMTP=GLOB(0x82616e0)>>> RCPT TO:<>
Net::SMTP: Unexpected EOF on command channel at line 211
Sending test message to -->
Exiting eval via next at line 254, <DATA> line 11.
Sending test message to -->
Exiting eval via next at line 254, <DATA> line 12.

NOTE:  after the EOF error server stops replying completely.  That's what I called "the script going awry" -- I can't regain the control of it.
I test the connection every email by this line:
if (undef($smtp)) die "smtp undef";  
but the server keeps going, without giving any response, so
apparently $smtp is still defined, yet it's practically dead..

Unexpected EOF happens on any of the lines where I have
$smtp->command();  #where "command" may be any of the to,from,datasend,etc.

And what's interesting is, i.e. in this case I have the command from line 254 as from the error above:
if ($smtp->to($to)==0) {print "bad recipient or unexpected EOF";};

self explanatory, but I'll reiterate:
$smtp->to() gives 0 if it's bad rcpt, or the EOF error.
it still gives 0 when the server doesn't reply anymore.
So I can't differentiate the two.  And depending on which one it is, I want different processing.  

So the (new) definition of the problem is .. how do I know when server stops replying.

I tried $smtp->response(), but it always times out, no matter what.
So, I am still trying things .. like maybe I'll try $smtp->code (); and see what it does.  It may differentiate between bad rcpt and EOF.  Then, if I know it's EOF I can halt the script without it going awry, and that's what I've been looking for.


LVL 51

Expert Comment

ID: 9634289
might be a reason for EOF, depending on the server ...

Author Comment

ID: 9634360
I have $smtp-quit(); at the end :)  I forgot to mention it last time.
However, the error happens in the loop, before $smtp->quit();


LVL 18

Accepted Solution

kandura earned 500 total points
ID: 9634584
If I understand the documentation for Net::Cmd correctly, $smtp->response() is a method for obtaining a response from the server. You should not call this yourself, Net::SMTP uses this internally. To be specific, it is being called after every $cmd->command() call (which sends a command to the server).

Please test the return values of $smtp->ok() or $smtp->code() and $smtp->message(), because they should contain the last response from the server.

If I'm reading Net::Cmd correctly, it will set code to 599 and message to 'Connection closed'.

BTW, I found your error message in Net::Cmd's getline() routine (on line 273), and it closes the connection right after it reports that. So you will know the connection is closed in this instance.

So, check $smtp->code(). If it equals 599, you know the connection has been closed, and you should reconnect (by setting $smtp = new Net::SMTP($server).

Hope this clarifies stuff a bit.


Author Comment

ID: 9654848
Thanks, Kandura !

eval and $smtp->code() helped.  $smtp->message() may also help if I'll need it later on.
I've regained control of the script ! :)

and thanks to everybody for hints and suggestions,

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Many time we need to work with multiple files all together. If its windows system then we can use some GUI based editor to accomplish our task. But what if you are on putty or have only CLI(Command Line Interface) as an option to  edit your files. I…
I have been pestered over the years to produce and distribute regular data extracts, and often the request have explicitly requested the data be emailed as an Excel attachement; specifically Excel, as it appears: CSV files confuse (no Red or Green h…
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
Six Sigma Control Plans

636 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question