-
usando Sistema;
usando System.Collections.Generic;
utilizando System.Net.Sockets;
usando System.IO;
usando System.Text;
usando System.Collections;
MailSender de clase pública
{
/// <resumen>
/// SMTP 服务器域名
/// </summary>
servidor de cadena pública
{
obtener {volver servidor; }
establecer {si (valor! = servidor) servidor = valor; }
} servidor de cadena privada = "";
/// <resumen>
/// SMTP 服务器端口 [默认为25]
/// </summary>
puerto int público
{
obtener {puerto de retorno; }
establecer {if (valor! = puerto) puerto = valor; }
} puerto int privado = 25;
/// <resumen>
/// 用户名 [如果需要身份验证的话]
/// </summary>
nombre de usuario de cadena pública
{
obtener { return nombre de usuario; }
set {if (valor! = Nombre de usuario) Nombre de usuario = valor; }
} cadena privada nombre de usuario = "";
/// <resumen>
/// 密码 [如果需要身份验证的话]
/// </summary>
contraseña de cadena pública
{
obtener {contraseña de retorno; }
establecer {if (valor! = contraseña) contraseña = valor; }
} contraseña de cadena privada = "";
/// <resumen>
/// 发件人地址
/// </summary>
cadena pública de
{
obtener { regresar de; }
establecer {si (valor! = de) de = valor; }
} cadena privada de = "";
/// <resumen>
/// 收件人地址
/// </summary>
cadena pública para
{
obtener {volver a; }
establecer {si (valor! = a) a = valor; }
} cadena privada a = "";
/// <resumen>
/// 发件人姓名
/// </summary>
cadena pública DeNombre
{
obtener {retorno deNombre; }
set {if (valor! = fromName) fromName = valor; }
} cadena privada fromName = "";
/// <resumen>
/// 收件人姓名
/// </summary>
cadena pública ToName
{
obtener {volver aNombre; }
set {if (valor! = toName) toName = valor; }
} cadena privada toName = "";
/// <resumen>
/// 邮件的主题
/// </summary>
Asunto de cadena pública
{
obtener { asunto de devolución; }
set {if (valor! = asunto) asunto = valor; }
} cadena privada asunto = "";
/// <resumen>
/// 邮件正文
/// </summary>
cuerpo de cadena pública
{
obtener {volver cuerpo; }
establecer {si (valor! = cuerpo) cuerpo = valor; }
} cuerpo de cadena privada = "";
/// <resumen>
/// 超文本格式的邮件正文
/// </summary>
cadena pública HtmlBody
{
obtener {return htmlBody; }
establecer {si (valor! = htmlBody) htmlBody = valor; }
} cadena privada htmlBody = "";
/// <resumen>
/// 是否是html格式的邮件
/// </summary>
bool público IsHtml
{
obtener {return isHtml; }
establecer {si (valor! = isHtml) isHtml = valor; }
} bool privado isHtml = false;
/// <resumen>
/// 语言编码 [默认为GB2312]
/// </summary>
cadena pública LanguageEncoding
{
obtener { return languageEncoding; }
establecer {si (valor! = codificación de idioma) codificación de idioma = valor; }
} cadena privada languageEncoding = "GB2312";
/// <resumen>
/// 邮件编码 [默认为8bit]
/// </summary>
cadena pública MailEncoding
{
obtener {codificación de retorno; }
establecer {si (valor! = codificación) codificación = valor; }
} codificación de cadena privada = "8 bits";
/// <resumen>
/// 邮件优先级 [默认为3]
/// </summary>
prioridad int pública
{
obtener {prioridad de retorno; }
establecer {si (valor! = prioridad) prioridad = valor; }
} prioridad int privada = 3;
/// <resumen>
/// 附件 [AdjuntoInfo]
/// </summary>
Adjuntos públicos de IList
{
obtener {devolver archivos adjuntos; }
// establecer { if (valor! = archivos adjuntos) archivos adjuntos = valor; }
} archivos adjuntos privados de ArrayList = new ArrayList();
/// <resumen>
/// 发送邮件
/// </summary>
SendMail público vacío()
{
// 创建TcpClient对象, 并建立连接
TcpClient tcp = nulo;
intentar
{
tcp = nuevo TcpClient(servidor, puerto);
}
captura (Excepción ex)
{
cadena err = ex.Mensaje;
lanzar una nueva excepción ("无法连接服务器");
}
ReadString(tcp.GetStream());//获取连接信息
// 开始进行服务器认证
// 如果状态码是250则表示操作成功
si (!Command(tcp.GetStream(), "EHLO Localhost", "250"))
lanzar una nueva excepción ("登陆阶段失败");
si (nombre de usuario! = "")
{
// 需要身份验证
if (!Command(tcp.GetStream(), "AUTH LOGIN", "334"))
lanzar una nueva excepción ("身份验证阶段失败");
nombre de cadenaB64 = ToBase64(nombre de usuario); // 此处将nombre de usuario转换为Base64码
if (!Command(tcp.GetStream(), nombreB64, "334"))
lanzar una nueva excepción ("身份验证阶段失败");
cadena passB64 = ToBase64(contraseña); // 此处将contraseña转换为Base64码
si (!Command(tcp.GetStream(), passB64, "235"))
lanzar una nueva excepción ("身份验证阶段失败");
}
// 准备发送
WriteString(tcp.GetStream(), "correo de: " + de);
WriteString(tcp.GetStream(), "rcpt a: " + a);
WriteString(tcp.GetStream(), "datos");
// 发送邮件头
WriteString(tcp.GetStream(), "Fecha: " + DateTime.Now); // 时间
WriteString(tcp.GetStream(), "De: " + fromName + "<" + from + ">"); // 发件人
WriteString(tcp.GetStream(), "Asunto: " + asunto); // 主题
WriteString(tcp.GetStream(), "Para:" + toName + "<" + to + ">"); // 收件人
//邮件格式
WriteString(tcp.GetStream(), "Tipo de contenido: multiparte/mixto; límite="límite-único-1"");
WriteString(tcp.GetStream(), "Responder a:" + de); // 回复地址
WriteString(tcp.GetStream(), "Prioridad X:" + prioridad); // 优先级
WriteString(tcp.GetStream(), "MIME-Version:1.0"); // MIME
// 数据ID,随意
// WriteString (tcp.GetStream(), "Message-Id: " + DateTime.Now.ToFileTime() + "@security.com ");
WriteString(tcp.GetStream(), "Content-Transfer-Encoding:" + codificación); // 内容编码
WriteString(tcp.GetStream(), "X-Mailer:JcPersonal.Utility.MailSender"); // 邮件发送者
WriteString(tcp.GetStream(), "");
WriteString(tcp.GetStream(), ToBase64("Este es un mensaje de varias partes en formato MIME."));
WriteString(tcp.GetStream(), "");
// 从此处开始进行分隔输入
WriteString(tcp.GetStream(), "--límite-único-1");
// 在此处定义第二个分隔符
WriteString(tcp.GetStream(), "Tipo de contenido: multiparte/alternativo; Límite="límite-único-2"");
WriteString(tcp.GetStream(), "");
si (!isHtml)
{
// 文本信息
WriteString(tcp.GetStream(), "--límite-único-2");
WriteString(tcp.GetStream(), "Tipo de contenido: text/plain;charset=" + languageEncoding);
WriteString(tcp.GetStream(), "Content-Transfer-Encoding:" + codificación);
WriteString(tcp.GetStream(), "");
WriteString(tcp.GetStream(), cuerpo);
WriteString(tcp.GetStream(), "");//一个部分写完之后就写如空信息,分段
WriteString(tcp.GetStream(), "--unique-boundary-2--");//分隔符的结束符号,尾巴后面多了--
WriteString(tcp.GetStream(), "");
}
demás
{
//html信息
WriteString(tcp.GetStream(), "--límite-único-2");
WriteString(tcp.GetStream(), "Tipo de contenido: text/html;charset=" + languageEncoding);
WriteString(tcp.GetStream(), "Content-Transfer-Encoding:" + codificación);
WriteString(tcp.GetStream(), "");
WriteString(tcp.GetStream(), htmlBody);
WriteString(tcp.GetStream(), "");
WriteString(tcp.GetStream(), "--unique-boundary-2--");//分隔符的结束符号,尾巴后面多了--
WriteString(tcp.GetStream(), "");
}
// 发送附件
// 对文件列表做循环
para (int i = 0; i < adjuntos.Count; i++)
{
WriteString(tcp.GetStream(), "--límite-único-1"); // 邮件内容分隔符
WriteString(tcp.GetStream(), "Tipo de contenido: aplicación/octeto-stream;nombre="" + ((AttachmentInfo)attachments[i]).FileName + """); // 文件格式
WriteString(tcp.GetStream(), "Codificación de transferencia de contenido: base64"); // 内容的编码
WriteString(tcp.GetStream(), "Content-Disposition:attachment;filename="" + ((AttachmentInfo)attachments[i]).FileName + """); // 文件名
WriteString(tcp.GetStream(), "");
WriteString(tcp.GetStream(), ((AttachmentInfo)adjuntos[i]).Bytes); // 写入文件的内容
WriteString(tcp.GetStream(), "");
}
Comando(tcp.GetStream(), ".", "250"); // 最后写完了,输入"."
// 关闭连接
tcp.Cerrar();
}
/// <resumen>
/// 向流中写入字符
/// </summary>
/// <param name="netStream">来自的流 de TcpClient</param>
/// <param name="str">写入的字符</param>
WriteString vacío protegido (NetworkStream netStream, string str)
{
cadena = cadena + " "; // 加入换行符
// 将命令行转化为byte[]
byte[] bWrite = Encoding.GetEncoding(languageEncoding).GetBytes(str.ToCharArray());
// 由于每次写入的数据大小是有限制的,那么我们将每次写入的数据长度定在75个字节,一旦命令长度超过了75,就分步写入.
int inicio = 0;
longitud int = bWrite.Length;
página int = 0;
tamaño entero = 75;
int recuento = tamaño;
intentar
{
si (longitud > 75)
{
// 数据分页
if ((largo / tamaño) * tamaño < largo)
página = largo / tamaño + 1;
demás
página = largo / tamaño;
para (int i = 0; i < página; i++)
{
inicio = i * tamaño;
si (i == página - 1)
recuento = longitud - (i * tamaño);
netStream.Write(bWrite, start, count);// 将数据写入到服务器上
}
}
demás
netStream.Write(bWrite, 0, bWrite.Length);
}
captura (excepción)
{
// 忽略错误
}
}
/// <resumen>
/// 从流中读取字符
/// </summary>
/// <param name="netStream">来自的流 de TcpClient</param>
/// <returns>读取的字符</returns>
cadena protegida ReadString(NetworkStream netStream)
{
cadena sp = nula;
byte[] por = nuevo byte[1024];
int size = netStream.Read(by, 0, by.Length);// 读取数据流
si (tamaño > 0)
{
sp = Encoding.Default.GetString(by);// 转化为String
}
devolver sp;
}
/// <resumen>
/// 发出命令并判断返回信息是否正确
/// </summary>
/// <param name="netStream">来自的流 de TcpClient</param>
/// <param nombre="comando">命令</param>
/// <param name="estado">正确的状态码</param>
/// <returns>是否正确</returns>
Comando bool protegido (NetworkStream netStream, comando de cadena, estado de cadena)
{
cadena sp = nula;
éxito bool = falso;
intentar
{
WriteString(netStream, comando);// 写入命令
sp = ReadString(netStream);// 接受返回信息
if (sp.IndexOf(estado) != -1)// 判断状态码是否正确
éxito = verdadero;
}
captura (excepción)
{
// 忽略错误
}
éxito de retorno;
}
/// <resumen>
/// Base64
/// </summary>
/// <param name="str">字符串</param>
/// <returns>Base64编码的字符串</returns>
cadena protegida ToBase64 (cadena cadena)
{
intentar
{
byte[] por = Encoding.Default.GetBytes(str.ToCharArray());
str = Convert.ToBase64String(por);
}
captura (excepción)
{
// 忽略错误
}
devolver cadena;
}
/// <resumen>
/// 附件信息
/// </summary>
estructura pública Información adjunta
{
/// <resumen>
/// 附件的文件名 [如果输入路径,则自动转换为文件名]
/// </summary>
cadena pública nombre de archivo
{
get {return fileName; }
establecer { nombre de archivo = Ruta.GetFileName (valor); }
} nombre de archivo de cadena privada;
/// <resumen>
/// 附件的内容 [由经Base64编码的字节组成]
/// </summary>
Bytes de cadena pública
{
obtener { devolver bytes; }
establecer {si (valor! = bytes) bytes = valor; }
} bytes de cadena privada;
/// <resumen>
/// 从流中读取附件内容并构造
/// </summary>
/// <param name="ifileName">附件的文件名</param>
/// <param nombre="flujo">流</param>
Información adjunta pública (cadena ifileName, secuencia de transmisión)
{
nombredearchivo = Ruta.GetFileName(ifileName);
byte[] por = nuevo byte[flujo.Longitud];
flujo.Leer(por, 0, (int)flujo.Longitud); // 读取文件内容
//格式转换
bytes = Convert.ToBase64String(por); // 转化为base64编码
}
/// <resumen>
/// 按照给定的字节构造附件
/// </summary>
/// <param name="ifileName">附件的文件名</param>
/// <param name="ibytes">附件的内容 [字节]</param>
información adjunta pública (cadena ifileName, byte [] ibytes)
{
nombredearchivo = Ruta.GetFileName(ifileName);
bytes = Convert.ToBase64String(ibytes); // 转化为base64编码
}
/// <resumen>
/// 从文件载入并构造
/// </summary>
/// <param nombre="ruta"></param>
Información adjunta pública (ruta de cadena)
{
nombredearchivo = Ruta.GetFileName(ruta);
Archivo FileStream = nuevo FileStream (ruta, FileMode.Open);
byte[] por = nuevo byte[archivo.Longitud];
archivo.Leer(por, 0, (int)archivo.Longitud); // 读取文件内容
//格式转换
bytes = Convert.ToBase64String(por); // 转化为base64编码
archivo.Cerrar();
}
}