【发布时间】:2015-05-08 08:55:48
【问题描述】:
由于我没有找到问题描述here 的解决方案,我决定使用sysread 和syswrite 与smtp 服务器进行对话。下面是我的测试代码:
sub test {
my ($dbh) = @_;
my $server = "smtp.mail.ru";
my $ip = $server;
$ip = inet_aton($ip);
$ip = inet_ntoa($ip);
$ip = &ip2long($ip);
my $port = 465;
my $pid = 0;
my $is_ssl = 1;
my $answer;
my $user = 'my_mail@mail.ru';
my $buff = 8192;
if (&choose_proxy($ip, $port, $dbh, $pid)) {
if (&connect($ip, $port, $is_ssl, $pid, $server)){
data_read($buff);
my $ehlo = "ehlo mydomain.com\n";
data_send($ehlo);
data_read($buff);
my $auth = "auth login\n";
data_send($auth);
data_read($buff);
my $smtpuser = encode_base64($user);
my $smtppassword = encode_base64('password');
data_send($smtpuser);
data_read($buff);
data_send($smtppassword);
data_read($buff);
my $mail = "mail from: <$user>\n";
data_send($mail);
data_read($buff);
my $to = 'my_mail@mail.ru';
$to = "rcpt to: <$to>\n";
data_send($to);
data_read($buff);
my $start = "DATA\n";
syswrite($socket, $start, length($start));
data_read($buff);
my $data = "test message\n";
data_send($data);
my $end .= ".\n";
data_send($end);
data_read($buff);
my $quit = "quit\n";
data_send($quit);
data_read($buff);
return $socket;
}
}
}
sub data_send {
my $data = shift;
if ($debug_smtp) {
print ">> $data";
}
syswrite($socket, $data, length($data));
}
sub data_read {
my $buff = shift;
my $data;
sleep(1);
sysread($socket, $data, $buff);
if ($debug_smtp) {
print "<< $data";
}
}
我有很多无法解决的问题和错误。
起初,有时!我在数据结束后得到:Use of uninitialized value $data in concatenation (.) or string at ...(data_send($end);)。
其次,data_send($end) 无法在 Gmail 上运行,所有这些代码都无法在 GMX 上运行。
第三,代码while {sysread($socket, $data, $buff);} 不起作用,我使用sleep(1),它不好。
最后,我收到了带有标题和消息正文的文件,但 syswrite 不适用于包含文件内容的变量。
如果有任何帮助,我将不胜感激,谢谢。
【问题讨论】:
-
没有错误检查,没有显示调试输出,并且您没有正确地使用 SMTP。如果您想手动完成所有 SMTP 工作,请先熟悉该标准的工作原理,即使用 RFC 2821。
-
这里只是测试方法,我还没有添加错误检查,你说的是什么调试?根据 RFC,我做错了什么?
-
"...根据 RFC,我做错了什么" - 至少您没有正确阅读响应。这些是单行或多行响应,不能保证仅使用 sysread 就能获得完整响应。响应还有一个需要检查的状态代码。此外,不保证 syswrite 会写入您提供的所有内容。对于 DATA,有一种特殊的方式需要准备数据。此外,行尾是 CR LF 而不仅仅是 LF ....
-
那你能告诉我用什么来保证传送和接收消息吗?我稍后添加的代码检查。我使用
.\r\n,结果相似 -
保证交付:检查您从 sysread 返回的长度,如果未达到长度,则发送更多。接收:读取行,检查状态代码,读取标准如何获得响应。至于 CR LF 与 LF - 有些服务器不在乎,有些则在乎。