Solved

Net::SMTP Unexpected EOF error

Posted on 2003-10-25
12
3,531 Views
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 smtp.pl 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 ?  

thanks,
Dennis
0
Comment
Question by:dennismv
  • 5
  • 3
  • 3
  • +1
12 Comments
 
LVL 18

Expert Comment

by:kandura
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.
0
 
LVL 51

Expert Comment

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

Author Comment

by:dennismv
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->mail($mailfrom);        

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

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

# body.  
$smtp->datasend("$message\n\n");
$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.

Dennis
0
Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

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.

 
LVL 5

Expert Comment

by:amandeep
ID: 9622134
dennismv,

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.

Aman
:-)


0
 

Author Comment

by:dennismv
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 ?

Dennis

0
 
LVL 51

Expert Comment

by:ahoffmann
ID: 9622171
what is $server set too?
and you're missing a final
$smtp->quit();
0
 
LVL 18

Expert Comment

by:kandura
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.

HTH,
Kandura
0
 

Author Comment

by:dennismv
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:<me@domain.com>
Net::SMTP=GLOB(0x82616e0)<<< 250 sender <me@domain.com> ok
Net::SMTP=GLOB(0x82616e0)>>> RCPT TO:<userto@domain.com>
Net::SMTP: Unexpected EOF on command channel at smtp.pl line 211
Sending test message to --> test@domain.com
Exiting eval via next at smtp.pl line 254, <DATA> line 11.
Sending test message to --> test@domain.com
Exiting eval via next at smtp.pl line 254, <DATA> line 12.
etc.

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.

Dennis

0
 
LVL 51

Expert Comment

by:ahoffmann
ID: 9634289
again:
  $smtp->quit();
might be a reason for EOF, depending on the server ...
0
 

Author Comment

by:dennismv
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();

Dennis

0
 
LVL 18

Accepted Solution

by:
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.

Kandura
0
 

Author Comment

by:dennismv
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,
Dennis
0

Featured Post

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

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

Suggested Solutions

I've just discovered very important differences between Windows an Unix formats in Perl,at least 5.xx.. MOST IMPORTANT: Use Unix file format while saving Your script. otherwise it will have ^M s or smth likely weird in the EOL, Then DO NOT use m…
Email validation in proper way is  very important validation required in any web pages. This code is self explainable except that Regular Expression which I used for pattern matching. I originally published as a thread on my website : http://www…
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…

830 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