我要实现如下功能: 
1、邮件群发:每天发邮件给十几万,甚至几十万指定用户。
2、邮件地址从数据库里读出(比如access,sql server)。
3、多线程发送
告诉我怎样实现,不管用什么方法手段(好的控件)
请告诉我具体的实现方案,当然告诉我大概思路也有分!有满意答案分数再加! 
有邮件群发的原理和例子更好啦
1000高分。

解决方案 »

  1.   

    <delphi网络编程)上有个例子,要是不怎么急的话我可以和你一块学着做
      

  2.   

    他主要使用的是websnap技术。通过web网络发送邮件。
    demo的界面不错,不过好像没有设计到数据库,但是我想我们可以将数据存放到数据库中。
      

  3.   

    呵呵,书上的。不过我可以下午将这个demo做好。
      

  4.   

    我以前做过发邮件的程序,不过是单线程,不知道对你是否有帮助
    如果需要可以mail to: [email protected]
      

  5.   

    一、 软件准备
    读者应该拥有一份C++ Builder3.0或者Delphi 4.0或以上版本的拷贝。另外,还要有一份支持ODBC接口的数据库拷贝,例如:Microsoft Access、Paradox、dBase、Microsoft SQL Server、IBM DB2、Oracle等等。该数据库可以是平面文件数据库,也可以是关系型数据库。在本文中使用的是Delphi 5.0和Microsoft Access。二、数据库设计该email数据库中共有三个表:User表,Subject表,link表,各个表的字段格式如下:
    link表的UserID字段引自User表的ID字段,Subscribe表的SubjectID字段引自Subjectx表的ID字段。如果您使用的数据库支持Trigger,mjh yidd Insert、Update、Delete的Trigger使User表和Subject表的ID字段具有唯一的值。三、 程序设计过程
    本程序需要的组件有:TdataBaseTquery、NMSmtp、TListBox组件。其中,Tquery组件负责数据库的查询工作,TdataBase负责数据库的连接工作,TListBox组件用来显示查询结果,NMSmtp组件用来发送E-Mail信息。本程序实现的功能有:
    1. 根据用户订阅的邮件主题,从数据库中查询出要发送的用户名称,电子邮件地址;
    2. 在已经查询出的用户中进行进一步的调节;
    3. 载入邮件正文,保存邮件正文;
    4. 发送邮件;
    5. 进行邮件发送状态的记录并保存。四、具体的设计细节
    本程序的VCL组件的属性:
    DataMOdule1,数据窗口。此外,还需要三个eidt文本框(分别输入发信人姓名、发信人邮件地址、邮件主题),及一个memo邮件正文输入域。
    Form2窗口,用户配置界面。需要注意的是,其中的Groupbox1和Groupbox2的Visible设为false,在查询出用户信息后再显示这些组件。
    1. 查询数据库
    在配置用户信息的窗体的FormCreat事件中,需要将数据库中的所有的邮件主题查询出来,显示在一个ComboBox组件中。其主要代码如下:
    procedure TForm2.FormCreate(Sender: TObject);
    var
    i:integer;
    begin
    Query1.Active:=false; //在对TQuery组件进行查询之前,必须要关闭TQuery组件,或者将其属性Active设为false;
    Query1.Active:=true; //打开TQuery组件
    for I:=0 to Query1.RecordCount-1 do
    begin
    ComboBox1.Items.Add(Query1.FieldValues[‘subject’]); //将查询主题加入到TComboBox中
    Query1.Next;
    end;
    Query1.First; //将TQuery的记录设为第一条
    ComboBox1.Text:=ComboBox1.Items[0];
    end;
    然后再根据ComboBox1中的主题查询用户和用户邮件地址。
    procedure TForm2.Button1Click(Sender: TObject);
    var
    i:integer;
    begin
    listbox1.Clear;
    listbox2.Clear; //清除两个ListBox中的内容,进行新的一次查询
    Query1.Active:=false;
    Query1.SQL.Clear;//清除TQuery的SQL语句
    if not checkbox1.checked then//如果选择发送给订阅相应主题的用户
    begin
    Query1.SQL.Add(‘SELECT user.username, user.address, subject.subject ’+‘FROM (link INNER JOIN subject ON link.subjectid = subject.subjectid) INNER JOIN user ON link.userid = user.userid ’ +‘WHERE (((subject.subject)=:subject))’);
    Query1.Params[0].AsString:=ComboBox1.Text;//设置SQL中的主题参数
    end
    else //如果选择发送给全部用户
    Query1.SQL.Add(‘select user.username,user.address from user’);
    Query1.Prepare;
    Query1.Open;
    for i:=0 to Query1.RecordCount-1 do
    beginListBox1.Items.Add(expend(vartostr(Query 1.fieldvalues[‘username’]))+vartostr(Query1.FieldValues[‘address’]));
    //在订阅用户框中显示查询到的用户信息
    Query1.Next;
    end;
    label4.caption:=‘共有’+inttostr(listbox1.Items.Count)+‘项’;
    label5.Caption:=‘共有’+inttostr(listbox2.Items.Count)+‘项’;//显示查询到的用户数量
    GroupBox3.Visible:=true;
    GroupBox2.Visible:=true;
    Form2.Height:=554;
    end;
      

  6.   

    2. 调整用户信息
    双击需要发送的用户框中的条目,将其去掉;同样,双击不需要发送的用户框中的条目,将其加入发送用户框中,这部分代码相当简单,在此略去。
    3. 保存、载入邮件正文
    本程序中邮件正文是显示在TMemo1中的,保存和载入邮件正文可以使用TMemo1.lines.loadfromfile(string filename)方法及TMemo1.lines.savetofile(filenname)方法。实现代码如下:
    载入邮件正文:
    procedure TForm1.Button2Click(Sender: TObject);
    begin
    if (datasmtp.DataModule1.OpenDialog1.Execute) then
    begin
    Memo1.Lines.LoadFromFile(datasmtp.DataModule 1 .OpenDialog1.FileName);
    end;
    end;
    保存邮件正文:
    procedure TForm1.Button3Click(Sender: TObject);
    begin
    if (datasmtp.DataModule1.SaveDialog1.Execute) then
    begin
    Memo1.Lines.SaveToFile(datasmtp.DataModule 1.SaveDialog1.FileName);
    end;
    end;
    4. 发送邮件
    发送邮件使用的是Delphi和C++Builder中的VCL组件TNMSMTP,在此组件中封装了发送邮件的各种属性、方法和事件,其中PostMessage包含将要发送的邮件的相关信息,PostMessage中包括Attackments(邮件附件信息)、body(邮件正文)、Date(邮件发送日期)、FromAddress(发信人邮件地址)、FromName(发信人姓名)、LocalProgram(发送邮件程序的名称)、ReplyTo(回信地址)、subject(邮件主题)、ToAddress(收信人地址)、ToBlindCarbonCopy(邮件暗送地址)、ToCarbonCopy(邮件抄送地址)。此外,TNMSMTP的重要属性和方法有:Connected(是否与邮件服务器连接上)、Host(指定邮件服务器地址)、Port(端口号,默认为25)、Connect(与Host指定的服务器连接)、sendmail(发送邮件)。发送邮件的代码如下:
    procedure TForm3.Button3Click(Sender: TObject);
    var
    i:integer;
    begin
    with datasmtp.DataModule1.smtp.PostMessage do
    begin
    FromAddress:=form1.edit2.Text;
    FromName:=form1.edit1.Text;
    Subject:=form1.edit3.text;
    Body.Text:=form1.memo1.Text;
    end;
    with datasmtp.DataModule1.smtp do
    begin
    for i:=0 to form2.ListBox1.Items.Count-1 do
    begin
    PostMessage.ToAddress.Clear;
    PostMessage.ToAddress.Add(getaddress(form2.List Box1.items[i]));
    Host:=gethost(getaddress(form2.ListBox1.Items[i]));
    try
    datasmtp.DataModule1.smtp.Connect;
    except
    end;
    if datasmtp.datamodule1.smtp.connected then
    datasmtp.DataModule1.smtp.SendMail;
    end;
    end;
    end;
      

  7.   

    5. 记录邮件发送状态并保存日志
    使用TNMSMTP的各种事件(如,OnConnect、OnConnectFailed、OnFailure、OnHostResolved等等)记录邮件发送状态。实现过程请参见下面的代码:
    procedure TDataModule1.smtpConnect(Sender: TObject);
    var
    s:string;
    begin
    s:=timetostr(time)+‘正在连接’+smtp.Post Message.ToAddress.Strings[0]+‘的服务器,请稍候!’;
    form3.Label1.Caption:=s;
    form3.Memo1.Lines.Add(s);
    end;
    procedure TDataModule1.smtpConnectionFailed(Sender: TObject);
    var
    s:string;
    begin
    s:=timetostr(time)+‘连接’+smtp.Post Message.ToAddress.strings[0]+‘的服务器失败!’;
    form3.Label1.Caption:=s;
    form3.Memo1.lines.add(s);
    end;
    procedure TDataModule1.smtpSendStart(Sender: TObject);
    var
    s:string;
    begin
    s:=timetostr(time)+‘开始发送给’+smtp.postmessage.ToAddress.strings[0]+‘的邮件!’;
    form3.Label1.Caption:=s;
    form3.memo1.lines.add(s);
    end;
    procedure TDataModule1.smtpSuccess(Sender: TObject);
    var
    s:string;
    begin
    s:=timetostr(time)+‘成功发送给’+smtp.postmessage.ToAddress.strings[0]+‘的邮件!’;
    form3.Label1.Caption:=s;
    form3.memo1.Lines.add(s);
    end;
    procedure TDataModule1.smtpInvalidHost(var Handled: Boolean);
    var
    s:string;
    begin
    s:=timetostr(time)+‘:发送邮件给’+smtp.PostMessage.ToAddress.strings[0]+‘时,服务器’+smtp.Host+‘无效!’;
    form3.Label1.Caption:=s;
    form3.memo1.lines.add(s);
    end;
    procedure TDataModule1.smtpFailure(Sender: TObject);
    var
    s:string;
    begin
    s:=timetostr(time)+‘:给’+smtp.PostMessage.ToAddress.strings[0]+‘的邮件发送失败!’;
    form3.Label1.Caption:=s;
    form3.memo1.Lines.add(s);
    end;
    procedure TDataModule1.smtpHostResolved(Sender: TComponent);
    var
    s:string;
    begin
    s:=timetostr(time)+‘:已经解析出’+smtp.PostMessage.ToAddress.strings[0]+‘的邮件服务器地址!’;
    form3.Label1.Caption:=s;
    form3.memo1.Lines.add(s);
    end;
    保存日志的代码如下:
    procedure TForm3.Button1Click(Sender: TObject);
    begin
    datasmtp.DataModule1.SaveDialog1.FileName:=datetostr(date)+‘邮件日志.txt’;
    if datasmtp.DataModule1.SaveDialog1.Execute then
    memo1.Lines.SaveToFile(datasmtp.DataModule1.SaveDialog1.FileName);
    end;使用TNMSMTP组件我们可以方便地实现批量发送电子邮件的功能,而如果将其组件使用在NSAPI中,加上高度的密码控制,我们就可以实现一个像在线邮局263一样的提供邮件服务的网站了。除了发送纯文本的邮件之外,TNMSMTP组件还可以通过TpostMessage中的Attachments属性粘贴附件,从而实现其他格式的文件发送。在本文的源代码中已经加上了发送附件的功能,请参考源程序 。另外,本文中的SMTP服务器是smtp.加上服务器主机名,如[email protected]的服务器就是smtp.263.net,如果您的smtp服务器不是这种规则,请修改源程序。
    本程序使用Delphi5.0,在Windows98中文版下调试通过。
    原作者:黄剑  思路应该可以了吧!自己改个多线程的吧!