Отчет по лабораторной работе №2 по дисциплине «Сети ЭВМ и телекоммуникации»
Национальный исследовательский
Томский Политехнический университет
Институт – Кибернетический Центр
Направление – Информатика и вычислительная техника
Кафедра – Оптимизации систем управления
Программная реализация
протокола высокого уровня
Отчет по лабораторной работе № 2
по дисциплине «Сети ЭВМ и телекоммуникации»
Выполнил
Студент группы 8в83 ___________ А.В. Колчанов
Проверил ___________ В. А. Дорофеев
Томск 2011
Цель работы: научиться создавать клиентские и серверные приложения с использованием сокетов.
Задание: Разработать приложение, выполняющее роль клиента или сервера для одного из протоколов высокого уровня:
HTTP
SMTP
POP3
FTP
Другой (по согласованию с преподавателем)
При выполнении этого задания можно работать в паре: один человек может взять на себя написание серверной части, другой – клиентской. При одиночной работе допустимо использовать сторонние серверы или клиенты, не требующие установки или находящиеся в сети.
Недопустимо использование высокоуровневых протоколов или классов, реализующих указанную функциональность: в качестве инструмента должны использоваться только классы и процедуры для работы с сокетами, которые встроены в основную библиотеку классов выбранного языка.
В окне программ должна быть предусмотрена возможность просмотра логов: полных текстов запросов и ответов на них.
В отчете приведите исходные тексты обоих программ, а также снимки окон программ в процессе работы.
Выполнение работы
Приложение для Windows 7 реализовано на языке C# двумя классами: NANMessage и NANSmtpClient. Класс NANMessage хранит в себе поля темя письма, адреса отправителя и получателя и текста письма. Класс NANSmtpClient реализует простейший SMTP клиент, работающий с почтовым сервером через сокеты.
Программная реализация класса NANMessage:
class NANMessage { private string nanMessageTo; private string nanMessageFrom; private string nanMesageCopy; private string nanMessageSubject; private string nanMessageBody; /// /// Тело письма (вложения) /// public List public StringBuilder nanMessageHeader = new StringBuilder(); /// /// Кому /// public string To { get { return nanMessageTo; } set { nanMessageTo = value; } } /// /// От кого /// public string From { get { return nanMessageFrom; } set { nanMessageFrom = value; } } /// /// Копия /// public string Copy { get { return nanMesageCopy; } set { nanMesageCopy = value; } } /// /// Тема /// public string Subject { get { return nanMessageSubject; } set { nanMessageSubject = value; } } /// /// Тело письма (текст) /// public string Body { get { return nanMessageBody; } set { nanMessageBody = value; } } public void Header() { //от кого nanMessageHeader.Append("From: " + From + "\r\n"); //кому string[] Tos = To.Split(new char[] { ';' }); nanMessageHeader.Append("To: "); for (int i = 0; i < Tos.Length; i++) { nanMessageHeader.Append(i > 0 ? "," : ""); nanMessageHeader.Append(Tos[i]); } nanMessageHeader.Append("\r\n"); //копия if (Copy != null) { Tos = Copy.Split(new char[] { ';' }); nanMessageHeader.Append("Cc: "); for (int i = 0; i < Tos.Length; i++) { nanMessageHeader.Append(i > 0 ? "," : ""); nanMessageHeader.Append(Tos[i]); } nanMessageHeader.Append("\r\n"); } //дата и время nanMessageHeader.Append("Date: "); nanMessageHeader.Append(DateTime.Now.ToUniversalTime().ToString("r", System.Globalization.DateTimeFormatInfo.InvariantInfo)); nanMessageHeader.Append("\r\n"); //тема nanMessageHeader.Append("Subject: " + CEnCode(Subject) + "\r\n"); nanMessageHeader.Append("X-Mailer: NANSmtpClient v1.0\r\n"); //тело письма (текст) string MsgBody = Body; if (!MsgBody.EndsWith("\r\n")) MsgBody += "\r\n"; nanMessageHeader.Append("\r\n"); nanMessageHeader.Append(MsgBody); nanMessageHeader.Append(".\r\n"); nanMessageHeader.Append("\r\n"); nanMessageHeader.Append("\r\n"); } private string CEnCode(string str) { bool needConvert = false; foreach (char c in str) { if (c > 127) { needConvert = true; break; } } if (needConvert) { string retVal = "=?" + "utf-8" + "?" + "B?"; retVal += Convert.ToBase64String(System.Text.Encoding.GetEncoding("utf-8").GetBytes(str)); retVal += "?="; return retVal; } return str; } } |
Программная реализация класса NANSmtpClient:
class NANSmtpClient { private string nanSmtpUser; private string nanSmtpPassword; private Socket s; private string h; private enum SMTPResponse : int { CONNECT_SUCCESS = 220, GENERIC_SUCCESS = 250, DATA_SUCCESS = 354, QUIT_SUCCESS = 221, LOGIN_SUCCESS = 235, AUTH_SUCCESS = 334 } /// /// Имя пользователя /// public string User { get { return nanSmtpUser; } set { nanSmtpUser = value; } } public string Log() { return h; } /// /// Пароль /// public string Password { get { return nanSmtpPassword; } set { nanSmtpPassword = value; } } public NANSmtpClient(string nanSmtpServer, int nanSmtpPort) { IPHostEntry IPhst = Dns.Resolve(nanSmtpServer); IPEndPoint endPt = new IPEndPoint(IPhst.AddressList[0], nanSmtpPort); s = new Socket(endPt.AddressFamily, SocketType.Stream, ProtocolType.Tcp); s.Connect(endPt); } private static void SenddataBase64(Socket s, string msg) { string tmp = System.Convert.ToBase64String(Encoding.ASCII.GetBytes(msg)) + "\r\n"; byte[] _msg = Encoding.ASCII.GetBytes(tmp); s.Send(_msg, 0, _msg.Length, SocketFlags.None); } private static void Senddata(Socket s, string msg) { byte[] _msg = Encoding.ASCII.GetBytes(msg); s.Send(_msg, 0, _msg.Length, SocketFlags.None); } private static bool Check_Response(Socket s, SMTPResponse response_expected) { string sResponse; int response; byte[] bytes = new byte[1024]; while (s.Available == 0) { System.Threading.Thread.Sleep(100); } s.Receive(bytes, 0, s.Available, SocketFlags.None); sResponse = Encoding.ASCII.GetString(bytes, 0, bytes.Length); response = Convert.ToInt32(sResponse.Substring(0, 3)); if (response != (int)response_expected) return false; return true; } /// /// Закрываем соединение и освобождаем связанные ресурсы /// public void Close() { s.Close(); } /// /// Отпрвляем письмо /// /// само письмо /// public bool Send(NANMessage msg) { int tmp = msg.From.IndexOf("@", 0, msg.From.Length); string domain = msg.From.Substring(tmp + 1, msg.From.Length - tmp - 1); if (!Check_Response(s, SMTPResponse.CONNECT_SUCCESS)) { s.Close(); return false; } h = ""; Senddata(s, string.Format("EHLO {0}\r\n", domain)); h += string.Format("EHLO {0}\r\n", domain) + "\n\r"; if (!Check_Response(s, SMTPResponse.GENERIC_SUCCESS)) { //MessageBox.Show("Нет ответа сервера", "Topmail", MessageBoxButtons.OK, MessageBoxIcon.Error); h += "Нет ответа сервера"; s.Close(); return false; } Senddata(s, "AUTH LOGIN\r\n"); h += "AUTH LOGIN\r\n" + "\n\r"; if (!Check_Response(s, SMTPResponse.AUTH_SUCCESS)) { //MessageBox.Show("Неправильный логин или пароль", "Topmail", MessageBoxButtons.OK, MessageBoxIcon.Error); h += "Неправильный логин или пароль"; s.Close(); return false; } SenddataBase64(s, User); if (!Check_Response(s, SMTPResponse.AUTH_SUCCESS)) { h += "Неправильный логин или пароль"; s.Close(); return false; } SenddataBase64(s, Password); if (!Check_Response(s, SMTPResponse.LOGIN_SUCCESS)) { h += "Неправильный логин или пароль"; s.Close(); return false; } Senddata(s, string.Format("MAIL From: {0}\r\n", msg.From)); h += string.Format("MAIL From: {0}\r\n", msg.From) + "\n\r"; if (!Check_Response(s, SMTPResponse.GENERIC_SUCCESS)) { MessageBox.Show("Ошибка при отправке письма", "Topmail", MessageBoxButtons.OK, MessageBoxIcon.Error); s.Close(); return false; } string _To = msg.To; string[] Tos = _To.Split(new char[] { ';' }); foreach (string To in Tos) { Senddata(s, string.Format("RC1PT TO: {0}\r\n", To)); h += string.Format("RCPT TO: {0}\r\n", To) + "\n\r"; if (!Check_Response(s, SMTPResponse.GENERIC_SUCCESS)) { MessageBox.Show("Ошибка при отправке письма", "Topmail", MessageBoxButtons.OK, MessageBoxIcon.Error); s.Close(); return false; } } if (msg.Copy != null) { Tos = msg.Copy.Split(new char[] { ';' }); foreach (string To in Tos) { Senddata(s, string.Format("RCPT TO: {0}\r\n", To)); h += string.Format("RCPT TO: {0}\r\n", To) + "\n\r"; if (!Check_Response(s, SMTPResponse.GENERIC_SUCCESS)) { MessageBox.Show("Ошибка при отправке письма", "Topmail", MessageBoxButtons.OK, MessageBoxIcon.Error); s.Close(); return false; } } } Senddata(s, ("DATA\r\n")); h += ("DATA\r\n") + "\n\r"; if (!Check_Response(s, SMTPResponse.DATA_SUCCESS)) { MessageBox.Show("Ошибка при отправке письма", "Topmail", MessageBoxButtons.OK, MessageBoxIcon.Error); s.Close(); return false; } msg.Header(); Senddata(s, msg.nanMessageHeader.ToString()); h += (msg.nanMessageHeader.ToString()) + "\n\r"; if (!Check_Response(s, SMTPResponse.GENERIC_SUCCESS)) { s.Close(); return false; } Senddata(s, "QUIT\r\n"); h += "QUIT\r\n" + "\n\r"; Check_Response(s, SMTPResponse.QUIT_SUCCESS); s.Close(); return true; } } |
Код работы с этими двумя классами:
NANMessage msg = new NANMessage(); msg.To = textBox1.Text; msg.From = @"[email protected]"; msg.Subject = textBox2.Text; msg.Body = textBox3.Text; NANSmtpClient client = new NANSmtpClient(@"smtp.mail.ru", 25); client.User = @"andrey4623"; client.Password = ""; client.Send(msg); client.Close(); MessageBox.Show("Your message has been sent", "Topmail", MessageBoxButtons.OK, MessageBoxIcon.Information); |
Скриншот приложения после запуска:

Скриншот приложения после успешной отправки почты:

Заключение
В ходе выполнения этой лабораторной работы было разработано приложение на языке C# в среде Visual Studio 2010, работающее через сокеты с почтовым сервером mail.ru. По сути, мы повторили свои действия из прошлой лабораторной работы, но здесь разработали удобную программу, позволяющую красиво отправить почту.
страница 1
скачать
Другие похожие работы: