在没有smtp的情况下在Delphi中发送电子邮件并在服务器上使用php功能

时间:2022-02-25 18:15:16

Using Delphi, i want to send a text message to my web server using winsock, and then use an email php function on the server to post the message.

使用Delphi,我想使用winsock向我的Web服务器发送文本消息,然后在服务器上使用电子邮件php函数发布消息。

First i have done the sending procedure (Procedure SendEmail): it reads a text file (log) and POST it to my server. On the server, the message is received by aa email php function named email.php (see content of that function below):

首先我完成了发送过程(Procedure SendEmail):它读取文本文件(log)并将其发送到我的服务器。在服务器上,消息由一个名为email.php的电子邮件php函数接收(请参阅下面该函数的内容):

Procedure SendEmail;

var
WSADat:WSAData; // winsock.pas
Texto:TextFile;
Client:TSocket;
Info,Posting,Linha,Content:String;
SockAddrIn:SockAddr_In; // winsock.pas
begin
try
if not FileExists(Log) then exit;
AssignFile(Texto, Log); // text to be sent 
Reset(Texto);
while not Eof(Texto) do
begin
ReadLn(Texto, Linha);
Content:=Content+#13#10+Linha;
end;
CloseFile(Texto);
DeleteFile(PChar(Log));
WSAStartUp(257,WSADat);
Client:=Socket(AF_INET,SOCK_STREAM,IPPROTO_IP);
SockAddrIn.sin_family:=AF_INET;
SockAddrIn.sin_port:=htons(80);
SockAddrIn.sin_addr.S_addr:=inet_addr('60.64.10.42'); // myserver IP
if Connect(Client,SockAddrIn,SizeOf(SockAddrIn))=0 then begin
Info:='Sender='+CFG.Email+'&content='+Content;
Posting:='POST /blogwp/email.php HTTP/1.0' #13#10
'Connection: close' #13#10
'Content-Type: application/x-www-form-urlencoded' #13#10
'Content-Length: '+IntToStr(Length(Info)) #13#10
'Host: http://myserver.com' #13#10
'Accept: text/html' +#13#10+#13#10+
Info+#13#10;
Send(Client,Pointer(Posting)^,Length(Posting),0);
end;
CloseSocket(Client);
except
exit;
end;
end;
[... some  mutex test...]
end.

Description of email.php function on the server:

服务器上email.php功能的说明:

<?php
$to =$_POST["sender"];
$subject ="mymessages";
$message =$_POST["content"];
$from ="From: some at somedomain dot com";

$headers =implode("\n",array("From: $headers","Subject: $subject","Return-Path: $headers","MIME-Version: 1.0?","X-Priority: 3","Content-Type: text/html" ));

$flag = mail($to,$subject,$message,$from); // create variables

if($flag)
{
echo "ok!";
}
else
{
echo "no ok =/";
}
?>

(note:I have followed this guide for the php mail function: http://us3.php.net/manual/en/book.mail.php )

(注意:我已经按照本指南的说明进行了php邮件功能:http://us3.php.net/manual/en/book.mail.php)

The general idea here is to send the message to the server not using smtp. However, as far as i can see, it looks like the mail is dropped at my server. I'm pretty confident of the procedure, but not sure about the php mail function. The thing is not easy to debug. ANY idea what is going wrong? OR any other look alike solution?

这里的一般想法是不使用smtp将消息发送到服务器。但是,据我所知,看起来邮件被丢弃在我的服务器上。我对这个程序很有信心,但不确定php邮件功能。事情不容易调试。出了什么问题?或任何其他相似的解决方案?

Any help will be appreciated. Thanks.

任何帮助将不胜感激。谢谢。

[EDIT] I have also ask support at my server site concerning use of smtp. Looks like i cannot send any mail (using smtp) if no check is done first:

[编辑]我也在我的服务器网站上询问有关使用smtp的支持。如果没有先检查,我看起来无法发送任何邮件(使用smtp):

We use pop-before-smtp mail authentication. You first need to

check the mail before you can send any. You also do not set smtp authentication in your e-mail client settings. Once you have checked the mail with POP authentication is not needed.

检查邮件,然后才能发送任何邮件。您也不要在电子邮件客户端设置中设置smtp身份验证。一旦您使用POP身份验证检查邮件就不需要了。

We use POP before SMTP authentication as it is a fairly

secure way to prevent spammers and open relays. Unfortunately, this is the configuration that we have chosen. For users who wish to send out mailing lists, we have the Mailman ValueApp, but for standard emailing, POP before SMTP is how the server is setup.

安全的方法来防止垃圾邮件发送者和开放中继。不幸的是,这是我们选择的配置。对于希望发送邮件列表的用户,我们有Mailman ValueApp,但对于标准电子邮件,SMTP之前的POP是服务器的设置方式。

6 个解决方案

#1


The following line is wrong:

以下行错了:

$headers =implode("\n",array("From: $headers","Subject: $subject","Return-Path: $headers","MIME-Version: 1.0?","X-Priority: 3","Content-Type: text/html" ));

It should be

它应该是

$headers =implode("\r\n", array("From: $from","Return-Path: $from","MIME-Version: 1.0","X-Priority: 3","Content-Type: text/html"));

although your mail server may be broken and require "\n".

虽然您的邮件服务器可能已损坏并需要“\ n”。

also $from should be the email address only, and not include "From: ".

$ from也应仅为电子邮件地址,不包括“发件人:”。

There's no need to set a Subject header - PHP will do that for you.

没有必要设置Subject标题 - PHP会为您做到这一点。

#2


You need to make sure that the case of the POST value names are matching - you have

您需要确保POST值名称的大小写匹配 - 您有

$to =$_POST["sender"];

and

Info:='Sender='+CFG.Email

#3


Since you noted that the ISP requires authentication via POP-before-SMTP, you should look into using something like PHP Mailer which can facilitate this kind of interaction - or roll your own using the PHP functions for POP (which happen to be exactly the same as the ones for IMAP and NNTP).

由于您注意到ISP需要通过POP-before-SMTP进行身份验证,因此您应该考虑使用像PHP Mailer这样可以促进这种交互的东西 - 或者使用POP的PHP功能(这恰好是相同的)作为IMAP和NNTP的那些)。

#4


On the PHP side you can use fsockopen(), fputs(), fgets(), and fclose() to handle your connection needs to the POP server. The PHP help for fsockopen() should give you the details you need.

在PHP端,您可以使用fsockopen(),fputs(),fgets()和fclose()来处理对POP服务器的连接需求。 fsockopen()的PHP帮助应该为您提供所需的详细信息。

Side note: Perhaps not an issue but you will want to make sure you have not created a hybrid of an open relay (letting others use your email.php endpoint for sending e-mail on your behalf).

旁注:也许不是问题,但您需要确保没有创建开放中继的混合(让其他人使用您的email.php端点代表您发送电子邮件)。

#5


To test your PHP code

测试你的PHP代码

Why don't you try writing to a file? I would write to a file on the server with the date/time and the logfile contents, then access it from http://myserver.com/log.txt

你为什么不尝试写一个文件?我会写一个服务器上的文件,其中包含日期/时间和日志文件内容,然后从http://myserver.com/log.txt访问它

As for the Delphi part:

至于Delphi部分:

I wouldn't use sockets directly, Why don't you use libraries like Indy (TIDHTTP).

我不会直接使用套接字,为什么不使用像Indy(TIDHTTP)这样的库。

Using it would be much simpler.

使用它会简单得多。

The POST would be something like IdHttp1.Post(...)

POST会像IdHttp1.Post(...)

#6


OK thanks ... I have applied the corrections. Now i have exactly:

好的,谢谢...我已经应用了更正。现在我确切地说:

Procedure EnviarEmail;
var
  WSADat:WSAData;
  Texto:TextFile;
  Client:TSocket;
  Info,Posting,Linha,Content:String;
  SockAddrIn:SockAddr_In;
begin
  try
    if not FileExists(Log) then exit;
    AssignFile(Texto, Log);
    Reset(Texto);
    while not Eof(Texto) do
    begin
      ReadLn(Texto, Linha);
      Content:=Content+#13#10+Linha;
    end;
    CloseFile(Texto);
    DeleteFile(PChar(Log));
    WSAStartUp(257,WSADat);
    Client:=Socket(AF_INET,SOCK_STREAM,IPPROTO_IP);
    SockAddrIn.sin_family:=AF_INET;
    SockAddrIn.sin_port:=htons(80);
    SockAddrIn.sin_addr.S_addr:=inet_addr('86.88.10.42');
    if Connect(Client,SockAddrIn,SizeOf(SockAddrIn))=0 then begin
      Info:='Sender='+CFG.Email+'&Content='+Content;
      Posting:='POST /blogwp/email.php HTTP/1.0'               +#13#10+
             'Connection: close'                               +#13#10+
             'Content-Type: application/x-www-form-urlencoded' +#13#10+
             'Content-Length: '+IntToStr(Length(Info))         +#13#10+
             'Host: http://somedomain.com'                     +#13#10+
             'Accept: text/html'                               +#13#10+#13#10+
             Info+#13#10;
      Send(Client,Pointer(Posting)^,Length(Posting),0);
    end;
    CloseSocket(Client);
   // ShowMessage('INFO == ' +Info + ' POSTING == '+ Posting);
  except
    exit;
  end;
end;
[... some mutex check...]

The email.php on server is:

服务器上的email.php是:

<?php
$to =$_POST["Sender"];
$subject ="mymessages";
$message =$_POST["content"];
$from ="From: some at somedomain dot com";

$headers =implode("\r\n", array("From: $from","Return-Path: $from","MIME-Version: 1.0","X-Priority: 3","Content-Type: text/html"));

$flag = mail($to,$subject,$message,$from); // create variables

if($flag)
{
echo "ok!";
}
else
{
echo "no ok =/";
}
?>

Still get no mail. ShowMessage in the procedure show me something like this for the info variable:

仍然没有邮件。程序中的ShowMessage为info变量显示了这样的东西:

Sender=validEmailAddressContent=<..... data ....> 

This might be wrong - at least a space or a line feed (?) is missing between the address and the content. How exactly should be formated this 'info' variable?

这可能是错误的 - 地址和内容之间至少缺少空格或换行符(?)。究竟应该如何形成这个'info'变量?

Thanks.

#1


The following line is wrong:

以下行错了:

$headers =implode("\n",array("From: $headers","Subject: $subject","Return-Path: $headers","MIME-Version: 1.0?","X-Priority: 3","Content-Type: text/html" ));

It should be

它应该是

$headers =implode("\r\n", array("From: $from","Return-Path: $from","MIME-Version: 1.0","X-Priority: 3","Content-Type: text/html"));

although your mail server may be broken and require "\n".

虽然您的邮件服务器可能已损坏并需要“\ n”。

also $from should be the email address only, and not include "From: ".

$ from也应仅为电子邮件地址,不包括“发件人:”。

There's no need to set a Subject header - PHP will do that for you.

没有必要设置Subject标题 - PHP会为您做到这一点。

#2


You need to make sure that the case of the POST value names are matching - you have

您需要确保POST值名称的大小写匹配 - 您有

$to =$_POST["sender"];

and

Info:='Sender='+CFG.Email

#3


Since you noted that the ISP requires authentication via POP-before-SMTP, you should look into using something like PHP Mailer which can facilitate this kind of interaction - or roll your own using the PHP functions for POP (which happen to be exactly the same as the ones for IMAP and NNTP).

由于您注意到ISP需要通过POP-before-SMTP进行身份验证,因此您应该考虑使用像PHP Mailer这样可以促进这种交互的东西 - 或者使用POP的PHP功能(这恰好是相同的)作为IMAP和NNTP的那些)。

#4


On the PHP side you can use fsockopen(), fputs(), fgets(), and fclose() to handle your connection needs to the POP server. The PHP help for fsockopen() should give you the details you need.

在PHP端,您可以使用fsockopen(),fputs(),fgets()和fclose()来处理对POP服务器的连接需求。 fsockopen()的PHP帮助应该为您提供所需的详细信息。

Side note: Perhaps not an issue but you will want to make sure you have not created a hybrid of an open relay (letting others use your email.php endpoint for sending e-mail on your behalf).

旁注:也许不是问题,但您需要确保没有创建开放中继的混合(让其他人使用您的email.php端点代表您发送电子邮件)。

#5


To test your PHP code

测试你的PHP代码

Why don't you try writing to a file? I would write to a file on the server with the date/time and the logfile contents, then access it from http://myserver.com/log.txt

你为什么不尝试写一个文件?我会写一个服务器上的文件,其中包含日期/时间和日志文件内容,然后从http://myserver.com/log.txt访问它

As for the Delphi part:

至于Delphi部分:

I wouldn't use sockets directly, Why don't you use libraries like Indy (TIDHTTP).

我不会直接使用套接字,为什么不使用像Indy(TIDHTTP)这样的库。

Using it would be much simpler.

使用它会简单得多。

The POST would be something like IdHttp1.Post(...)

POST会像IdHttp1.Post(...)

#6


OK thanks ... I have applied the corrections. Now i have exactly:

好的,谢谢...我已经应用了更正。现在我确切地说:

Procedure EnviarEmail;
var
  WSADat:WSAData;
  Texto:TextFile;
  Client:TSocket;
  Info,Posting,Linha,Content:String;
  SockAddrIn:SockAddr_In;
begin
  try
    if not FileExists(Log) then exit;
    AssignFile(Texto, Log);
    Reset(Texto);
    while not Eof(Texto) do
    begin
      ReadLn(Texto, Linha);
      Content:=Content+#13#10+Linha;
    end;
    CloseFile(Texto);
    DeleteFile(PChar(Log));
    WSAStartUp(257,WSADat);
    Client:=Socket(AF_INET,SOCK_STREAM,IPPROTO_IP);
    SockAddrIn.sin_family:=AF_INET;
    SockAddrIn.sin_port:=htons(80);
    SockAddrIn.sin_addr.S_addr:=inet_addr('86.88.10.42');
    if Connect(Client,SockAddrIn,SizeOf(SockAddrIn))=0 then begin
      Info:='Sender='+CFG.Email+'&Content='+Content;
      Posting:='POST /blogwp/email.php HTTP/1.0'               +#13#10+
             'Connection: close'                               +#13#10+
             'Content-Type: application/x-www-form-urlencoded' +#13#10+
             'Content-Length: '+IntToStr(Length(Info))         +#13#10+
             'Host: http://somedomain.com'                     +#13#10+
             'Accept: text/html'                               +#13#10+#13#10+
             Info+#13#10;
      Send(Client,Pointer(Posting)^,Length(Posting),0);
    end;
    CloseSocket(Client);
   // ShowMessage('INFO == ' +Info + ' POSTING == '+ Posting);
  except
    exit;
  end;
end;
[... some mutex check...]

The email.php on server is:

服务器上的email.php是:

<?php
$to =$_POST["Sender"];
$subject ="mymessages";
$message =$_POST["content"];
$from ="From: some at somedomain dot com";

$headers =implode("\r\n", array("From: $from","Return-Path: $from","MIME-Version: 1.0","X-Priority: 3","Content-Type: text/html"));

$flag = mail($to,$subject,$message,$from); // create variables

if($flag)
{
echo "ok!";
}
else
{
echo "no ok =/";
}
?>

Still get no mail. ShowMessage in the procedure show me something like this for the info variable:

仍然没有邮件。程序中的ShowMessage为info变量显示了这样的东西:

Sender=validEmailAddressContent=<..... data ....> 

This might be wrong - at least a space or a line feed (?) is missing between the address and the content. How exactly should be formated this 'info' variable?

这可能是错误的 - 地址和内容之间至少缺少空格或换行符(?)。究竟应该如何形成这个'info'变量?

Thanks.