用indypop3server,indysmtpserver做个邮件服务器?(100分)

  • 主题发起人 主题发起人 andy san
  • 开始时间 开始时间
A

andy san

Unregistered / Unconfirmed
GUEST, unregistred user!
现在看不到DFW做邮件服务器了,大多是前几年的贴子,还没有结帐呢?
我想用delphi的indy 组件做个邮件服务器,想请教做过DFW给点思路,有源码最好.
在做这个的朋友可以进来共同讨论?
需要分数的我可以另开贴
 
其实就是socket服务端,监视那几个端口就可以了
 
TO 金卡绣球jk8.com:
这个我也清楚,能否深入的讲解一番,在线等待
 
过了N年了,我顶,我顶,我狂顶
 
{-----------------------------------------------------------------------------
Demo Name: POP3 Server demo
Author: Siamak Sarmady (email: sarmadys@onlineprogrammer.org)
Copyright: Indy Pit Crew
Purpose:
History: Added in some missing command handler comments - aon
Date: 27/10/2002 01:22:21
Checked with Indy version: 9.0 - Allen O'Neill - Springboard Technologies Ltd - http://www.springboardtechnologies.com
-----------------------------------------------------------------------------
Notes:

Demonstrates POP3 server events (by way of comment - NOT functional!)

}

unit MainFrm;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
IdBaseComponent, IdComponent, IdTCPServer, IdPOP3Server, StdCtrls;

type
TfrmMain = class(TForm)
btnExit: TButton;
IdPOP3Server1: TIdPOP3Server;
procedure btnExitClick(Sender: TObject);
procedure IdPOP3Server1CommandUSER(AThread: TIdPeerThread;
AUserName: String);
procedure IdPOP3Server1Connect(AThread: TIdPeerThread);
procedure IdPOP3Server1CommandPASS(AThread: TIdPeerThread;
APassword: String);
procedure IdPOP3Server1CommandSTAT(AThread: TIdPeerThread);
procedure IdPOP3Server1CommandLIST(AThread: TIdPeerThread;
AMessageNum: Integer);
procedure IdPOP3Server1CommandRETR(AThread: TIdPeerThread;
AMessageNum: Integer);
procedure IdPOP3Server1CommandDELE(AThread: TIdPeerThread;
AMessageNum: Integer);
procedure IdPOP3Server1CommandQUIT(AThread: TIdPeerThread);
procedure FormActivate(Sender: TObject);
procedure IdPOP3Server1CheckUser(AThread: TIdPeerThread;
LThread: TIdPOP3ServerThread);
procedure IdPOP3Server1DELE(ASender: TIdCommand; AMessageNum: Integer);
procedure IdPOP3Server1Exception(AThread: TIdPeerThread;
AException: Exception);
procedure IdPOP3Server1LIST(ASender: TIdCommand; AMessageNum: Integer);
procedure IdPOP3Server1QUIT(ASender: TIdCommand);
procedure IdPOP3Server1RETR(ASender: TIdCommand; AMessageNum: Integer);
procedure IdPOP3Server1RSET(ASender: TIdCommand);
procedure IdPOP3Server1STAT(ASender: TIdCommand);
procedure IdPOP3Server1TOP(ASender: TIdCommand; AMessageNum,
ANumLines: Integer);
procedure IdPOP3Server1UIDL(ASender: TIdCommand; AMessageNum: Integer);
private
{ Private declarations }
public
{ Public declarations }
end;

var
frmMain: TfrmMain;

implementation

{$R *.DFM}

//If user presses exit button close socket and exit
procedure TfrmMain.btnExitClick(Sender: TObject);
begin
if IdPop3Server1.Active=True then
IdPop3Server1.Active:=False;
Application.Terminate;
end;

//After completing a connection client sends a user name. We receive
//this username in AUserName variable in next function.
procedure TfrmMain.IdPOP3Server1CommandUSER(AThread: TIdPeerThread;
AUserName: String);
begin
AThread.Connection.WriteLn('+OK User Ok');
end;

//When a clinet connects to our server we must reply with +OK,
//if we are ready to accept mails. Otherwise if we are not ready
//we can issue an error.
// You may also wish to initialise some global vars here, set the POP3 box to locked state, etc.
procedure TfrmMain.IdPOP3Server1Connect(AThread: TIdPeerThread);
begin
AThread.Connection.WriteLn('+OK Indy MailServer Ready');
end;

//In reply to server request for a valid password, client delivers
//the password. We will receive password in this method and we can
//either accept or reject the password.
//This is done by either replying with +OK answer or an error code.
procedure TfrmMain.IdPOP3Server1CommandPASS(AThread: TIdPeerThread;
APassword: String);
begin
AThread.Connection.WriteLn('+OK Password OK');
end;

//When client asks for a statistic of messages server will answer
//by sending an +OK followed by number of messages and length of them
//Format of client message is STAT
procedure TfrmMain.IdPOP3Server1CommandSTAT(AThread: TIdPeerThread);
begin
AThread.Connection.WriteLn('+OK 1 40');
end;

//before retrieving messages, client asks for a list of messages
//Server responds with a +OK followed by number of deliverable
//messages and length of messages in bytes. After this a separate
//list of each message and its length is sent to client.
//here we have only one message, but we can continue with message
//number and its length , one per line and finally a '.' character.
//Format of client command is LIST
procedure TfrmMain.IdPOP3Server1CommandLIST(AThread: TIdPeerThread;
AMessageNum: Integer);
begin
AThread.Connection.WriteLn('+OK 1 messages (40 octets)');
AThread.Connection.WriteLn('1 40');
AThread.Connection.WriteLn('.');
end;


//Client initiates retrieving each message by issuing a RETR command
//to server. Server will respond by +OK and will continue by sending
//message itself. Each message is saved in a database uppon arival
//by smtp server and is now delivered to user mail agent by pop3 server.
//Here we do not read mail from a storage but we deliver a sample
//mail from inside program. We can deliver multiple mails using
//this method. Format of RETR command is something like
// RETR 1 or RETR 2 etc.
procedure TfrmMain.IdPOP3Server1CommandRETR(AThread: TIdPeerThread;
AMessageNum: Integer);
begin
AThread.Connection.WriteLn('+OK 40 octets');
AThread.Connection.WriteLn('From: demo@nevrona.com');
AThread.Connection.WriteLn('To: you@yourdomain.com ');
AThread.Connection.WriteLn('Subject: Hello ');
AThread.Connection.WriteLn('');
AThread.Connection.WriteLn('Hello world! This is email body.');
AThread.Connection.WriteLn('.');


end;

//Usually, messages are deleted after being retrieved from pop3 server
//This is done when client sents DELE command after retrieving a message
//Client command is something like DELE 1 which means delete message 1
procedure TfrmMain.IdPOP3Server1CommandDELE(AThread: TIdPeerThread;
AMessageNum: Integer);
begin
AThread.Connection.WriteLn('+OK message 1 deleted');

end;

//After doing every step client asks for ending session, this
//is done by sending QUIT message to server. Server will answer
//with +OK and some more information. Additional information
//is optional.
procedure TfrmMain.IdPOP3Server1CommandQUIT(AThread: TIdPeerThread);
begin
AThread.Connection.WriteLn('+OK OL POP3 server signing off (maildrop empty)');

end;

//Activate the server socket when activating server main window.
procedure TfrmMain.FormActivate(Sender: TObject);
begin
IdPop3Server1.Active:=True;
end;

// This is where you validate the user/pass credentials of the user logging in
procedure TfrmMain.IdPOP3Server1CheckUser(AThread: TIdPeerThread;
LThread: TIdPOP3ServerThread);
begin
// LThread.Username -> examine this for valid username
// LThread.Password -> examine this for valid password
// if the user/pass pair are valid, then respond with
// LThread.State := Trans
// to reject the user/pass pair, do not change the state
LThread.State := Trans;
end;

// This is where the client program issues a delete command for a particular message
procedure TfrmMain.IdPOP3Server1DELE(ASender: TIdCommand;
AMessageNum: Integer);
begin
// if the message has been deleted, then return a success command as follows;
// ASender.Thread.Connection.Writeln('+OK - Message ' + IntToStr(AMessageNum) + ' Deleted')
// otherwise, if there was an error in deleting the message, or the message number
// did not exist in the first place, then return the following:
// ASender.Thread.Connection.Writeln('-ERR - Message ' + IntToStr(AMessageNum) + ' not deleted because.... [reason]')
end;

procedure TfrmMain.IdPOP3Server1Exception(AThread: TIdPeerThread;
AException: Exception);
begin
// Handle any exceptions given by the thread here
end;

procedure TfrmMain.IdPOP3Server1LIST(ASender: TIdCommand;
AMessageNum: Integer);
begin
// Here you return a list of available messages to the client
end;

procedure TfrmMain.IdPOP3Server1QUIT(ASender: TIdCommand);
begin
// here is where the client has decided to close the connection
end;

procedure TfrmMain.IdPOP3Server1RETR(ASender: TIdCommand;
AMessageNum: Integer);
begin
// Here is where the client wishes to RETRieve a specific messages number
end;

procedure TfrmMain.IdPOP3Server1RSET(ASender: TIdCommand);
begin
// here is where the client wishes to reset the current state
// This may be used to reset a list of pending deletes, etc.
end;

procedure TfrmMain.IdPOP3Server1STAT(ASender: TIdCommand);
begin
// here is where the client has asked for the Status of the mailbox
end;

procedure TfrmMain.IdPOP3Server1TOP(ASender: TIdCommand; AMessageNum,
ANumLines: Integer);
begin
// This is where the cleint has requested the TOP X lines of a particular
// message to be sent to them
end;

procedure TfrmMain.IdPOP3Server1UIDL(ASender: TIdCommand;
AMessageNum: Integer);
begin
// This is where the client has requested the unique identifier (UIDL) of each
// message, or a particular message to be sent to them.
end;

end.
 
{-----------------------------------------------------------------------------
Demo Name: SMTPSever demo
Author: Andrew Neillans
Copyright: Indy Pit Crew
Purpose:
History:
Date: 27/10/2002 01:27:09
Checked with Indy version: 9.0 - Allen O'Neill - Springboard Technologies Ltd - http://www.springboardtechnologies.com
-----------------------------------------------------------------------------
Notes:

Demonstration of SMTPSerer (by use of comments only!! - read the RFC to understand how to
store and manage server data, and thus be able to use this component effectivly)

}

unit Main;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
IdBaseComponent, IdComponent, IdTCPServer, IdSMTPServer, StdCtrls,
IdMessage, IdEMailAddress;

type
TForm1 = class(TForm)
Memo1: TMemo;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
ToLabel: TLabel;
FromLabel: TLabel;
SubjectLabel: TLabel;
IdSMTPServer1: TIdSMTPServer;
Label4: TLabel;
Button1: TButton;
Button2: TButton;
procedure IdSMTPServer1ADDRESSError(AThread: TIdPeerThread;
const CmdStr: String);
procedure IdSMTPServer1CommandAUTH(AThread: TIdPeerThread;
const CmdStr: String);
procedure IdSMTPServer1CommandCheckUser(AThread: TIdPeerThread;
const Username, Password: String; var Accepted: Boolean);
procedure IdSMTPServer1CommandQUIT(AThread: TIdPeerThread);
procedure IdSMTPServer1CommandX(AThread: TIdPeerThread;
const CmdStr: String);
procedure IdSMTPServer1CommandMAIL(const ASender: TIdCommand;
var Accept: Boolean; EMailAddress: String);
procedure IdSMTPServer1CommandRCPT(const ASender: TIdCommand;
var Accept, ToForward: Boolean; EMailAddress: String;
var CustomError: String);
procedure IdSMTPServer1ReceiveRaw(ASender: TIdCommand;
var VStream: TStream; RCPT: TIdEMailAddressList;
var CustomError: String);
procedure IdSMTPServer1ReceiveMessage(ASender: TIdCommand;
var AMsg: TIdMessage; RCPT: TIdEMailAddressList;
var CustomError: String);
procedure IdSMTPServer1ReceiveMessageParsed(ASender: TIdCommand;
var AMsg: TIdMessage; RCPT: TIdEMailAddressList;
var CustomError: String);
procedure IdSMTPServer1CommandHELP(ASender: TIdCommand);
procedure IdSMTPServer1CommandSAML(ASender: TIdCommand);
procedure IdSMTPServer1CommandSEND(ASender: TIdCommand);
procedure IdSMTPServer1CommandSOML(ASender: TIdCommand);
procedure IdSMTPServer1CommandTURN(ASender: TIdCommand);
procedure IdSMTPServer1CommandVRFY(ASender: TIdCommand);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.IdSMTPServer1ADDRESSError(AThread: TIdPeerThread;
const CmdStr: String);
begin
// Send the Address Error String - this *WILL* be coded in eventually.
AThread.Connection.Writeln('500 Syntax Error in MAIL FROM or RCPT TO');
end;

procedure TForm1.IdSMTPServer1CommandAUTH(AThread: TIdPeerThread;
const CmdStr: String);
begin
// This is where you would process the AUTH command - for now, we send a error
AThread.Connection.Writeln(IdSMTPServer1.Messages.ErrorReply);
end;

procedure TForm1.IdSMTPServer1CommandCheckUser(AThread: TIdPeerThread;
const Username, Password: String; var Accepted: Boolean);
begin
// This event allows you to 'login' a user - this is used internall in the
// IdSMTPServer to validate users connecting using the AUTH.
Accepted := False;
end;

procedure TForm1.IdSMTPServer1CommandQUIT(AThread: TIdPeerThread);
begin
// Process any logoff events here - e.g. clean temp files
end;

procedure TForm1.IdSMTPServer1CommandX(AThread: TIdPeerThread;
const CmdStr: String);
begin
// You can use this for debugging :)

end;

procedure TForm1.IdSMTPServer1CommandMAIL(const ASender: TIdCommand;
var Accept: Boolean; EMailAddress: String);
begin
// This is required!
// You check the EMAILADDRESS here to see if it is to be accepted / processed.
// Set Accept := True if its allowed
Accept := True;
end;

procedure TForm1.IdSMTPServer1CommandRCPT(const ASender: TIdCommand;
var Accept, ToForward: Boolean; EMailAddress: String;
var CustomError: String);
begin
// This is required!
// You check the EMAILADDRESS here to see if it is to be accepted / processed.
// Set Accept := True if its allowed
// Set ToForward := True if its needing to be forwarded.
Accept := True;
end;

procedure TForm1.IdSMTPServer1ReceiveRaw(ASender: TIdCommand;
var VStream: TStream; RCPT: TIdEMailAddressList;
var CustomError: String);
begin
// This is the main event for receiving the message itself if you are using
// the ReceiveRAW method
// The message data will be given to you in VSTREAM
// Capture it using a memorystream, filestream, or whatever type of stream
// is suitable to your storage mechanism.
// The RCPT variable is a list of recipients for the message
end;

procedure TForm1.IdSMTPServer1ReceiveMessage(ASender: TIdCommand;
var AMsg: TIdMessage; RCPT: TIdEMailAddressList;
var CustomError: String);
begin
// This is the main event if you have opted to have idSMTPServer present the message packaged as a TidMessage
// The AMessage contains the completed TIdMessage.
// NOTE: Dont forget to add IdMessage to your USES clause!

ToLabel.Caption := AMsg.Recipients.EMailAddresses;
FromLabel.Caption := AMsg.From.Text;
SubjectLabel.Caption := AMsg.Subject;
Memo1.Lines := AMsg.Body;

// Implement your file system here :)
end;

procedure TForm1.IdSMTPServer1ReceiveMessageParsed(ASender: TIdCommand;
var AMsg: TIdMessage; RCPT: TIdEMailAddressList;
var CustomError: String);
begin
// This is the main event if you have opted to have the idSMTPServer to do your parsing for you.
// The AMessage contains the completed TIdMessage.
// NOTE: Dont forget to add IdMessage to your USES clause!

ToLabel.Caption := AMsg.Recipients.EMailAddresses;
FromLabel.Caption := AMsg.From.Text;
SubjectLabel.Caption := AMsg.Subject;
Memo1.Lines := AMsg.Body;

// Implement your file system here :)

end;

procedure TForm1.IdSMTPServer1CommandHELP(ASender: TIdCommand);
begin
// here you can send back a lsit of supported server commands
end;

procedure TForm1.IdSMTPServer1CommandSAML(ASender: TIdCommand);
begin
// not really used anymore - see RFC for information
end;

procedure TForm1.IdSMTPServer1CommandSEND(ASender: TIdCommand);
begin
// not really used anymore - see RFC for information
end;

procedure TForm1.IdSMTPServer1CommandSOML(ASender: TIdCommand);
begin
// not really used anymore - see RFC for information
end;

procedure TForm1.IdSMTPServer1CommandTURN(ASender: TIdCommand);
begin
// not really used anymore - see RFC for information
end;

procedure TForm1.IdSMTPServer1CommandVRFY(ASender: TIdCommand);
begin
// not really used anymore - see RFC for information
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
IdSMTPServer1.active := true;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
IdSMTPServer1.active := false;
end;

end.
 
谢谢weiliiu,
这是Indy9的Demo,我也有,我还有Indy10 的.在做或者是学习吗,需要的话我发给你.
再次感谢,继续讨论
 
问题解决了,开始放分
 
后退
顶部