谈用Delphi设计Email程序

本文详细介绍了如何使用Delphi编程实现Email的发送,包括基于SMTP协议的API方式和利用Web中转的邮件发送。文章提供了封装的网络API单元代码,用于连接、发送数据和关闭Socket,并展示了使用Base64编码的过程。此外,还探讨了Web中转邮件的原理,以及利用ASP组件JMail进行邮件转发的方法。
摘要由CSDN通过智能技术生成
传统的Email发送是基于smtp协议.也就是说,只要你的程序遵守RFC821规范的应答方式即可.实际应用中还有例如Web中转,ISAPI,MMX等等变种方式.最近不是有位权威说"代码就是开发文档"吗?所以,其它说话无须多讲,让我们直接开始code吧.

一:用API方式实现email邮件的发送.

  我们首先将常用的网络操作单元集合为一个单元.注意:我们下面讲述Web发送的时候还会用到这个单元.

unit Unit_MyWinSock;

{=======================================================
项目: 谈用Delphi设计Email程序 - 封装常用网络API单元
模块: 网络API单元
描述:
版本: 2004
日期: 2004-03-09
作者: 陈经韬
更新:
=======================================================}

interface
uses
Windows, WinSock;

function GetIpbyHostName(Host: string): string;
function StartNet(host: string; port: integer; var FSocket: integer): Boolean;
procedure StopNet(Fsocket: integer);
function SendData(FSocket: integer; SendStr: string): integer;
function GetData(FSocket: integer): string;
implementation

function StrPas(const Str: PChar): string;
begin
Result := Str;
end;

function StrCopy(Dest: PChar; const Source: PChar): PChar;
asm
PUSH EDI
PUSH ESI
MOV ESI,EAX
MOV EDI,EDX
MOV ECX,0FFFFFFFFH
XOR AL,AL
REPNE SCASB
NOT ECX
MOV EDI,ESI
MOV ESI,EDX
MOV EDX,ECX
MOV EAX,EDI
SHR ECX,2
REP MOVSD
MOV ECX,EDX
AND ECX,3
REP MOVSB
POP ESI
POP EDI
end;

function StrLen(const Str: PChar): Cardinal; assembler;
asm
MOV EDX,EDI
MOV EDI,EAX
MOV ECX,0FFFFFFFFH
XOR AL,AL
REPNE SCASB
MOV EAX,0FFFFFFFEH
SUB EAX,ECX
MOV EDI,EDX
end;
{============================================================}

function GetIpbyHostName(Host: string): string;
{
功能描述:获取主机的IP地址
入口参数:主机名称.例如 www.138soft.com
出口参数:主机IP地址
创建日期:2004,3,9.
修改记录:无
Author:jingtao. http://www.138soft.com
}
type
TaPInAddr = array[0..10] of PInAddr;
PaPInAddr = ^TaPInAddr;
var
phe: PHostEnt;
pptr: PaPInAddr;
i: Integer;
begin
Result := '';
phe := GetHostByName(pchar(Host));
if phe = nil then Exit;
pptr := PaPInAddr(Phe^.h_addr_list);
I := 0;
while pptr^[I] <> nil do
begin
if i = 0 then result := StrPas(inet_ntoa(pptr^[I]^));
Inc(I);
end;
end;

{============================================================}

function StartNet(host: string; port: integer; var FSocket: integer): Boolean;
{
功能描述:连接某IP地址
入口参数:
host:ip地址
port:端口
出口参数:
FSocket:连接后的Socket句柄
返回值:成功连接返回True,否则返回False
创建日期:2004,3,9.
修改记录:无
Author:jingtao. http://www.138soft.com
}
var
SockAddrIn: TSockAddrIn;
t: linger;

timeout: timeval;
r: TFDSet;
iTimeOut: integer;
ul, ul1: LongInt;
ret: integer;
begin
Result := False;
FSocket := socket(PF_INET, SOCK_STREAM, IPPROTO_IP);
if FSocket = invalid_socket then exit;

t.l_onoff := 1;
t.l_linger := 0;
setsockopt(FSocket, SOL_SOCKET, SO_LINGER, @t, sizeof(t)); {关闭Socket后立刻释放资源}

//set Recv and Send time out
iTimeOut := 6000; //设置发送超时6秒
if (setsockopt(FSocket, SOL_SOCKET, SO_SNDTIMEO, @iTimeOut, sizeof(TimeOut)) = SOCKET_ERROR) then Exit;
iTimeOut := 6000; //设置接收超时6秒
if (setsockopt(FSocket, SOL_SOCKET, SO_RCVTIMEO, @iTimeOut, sizeof(TimeOut)) = SOCKET_ERROR) then Exit;

//设置非阻塞方式连接
ul := 1;
ret := ioctlsocket(FSocket, FIONBIO, ul);
if (ret = SOCKET_ERROR) then Exit;

//连接
SockAddrIn.sin_addr.s_addr := inet_addr(PChar(host));
SockAddrIn.sin_family := PF_INET;
SockAddrIn.sin_port := htons(port);
ret := connect(FSocket, SockAddrIn, SizeOf(SockAddrIn));


//select 模型,即设置超时
FD_ZERO(r);
FD_SET(FSocket, r);
timeout.tv_sec := 5; //连接超时5秒
timeout.tv_usec := 0;
ret := select(0, nil, @r, nil, @timeout
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值