Файл: Разработка клиентского приложения передачи электронной почты с применением протоколов SMPT и UDP на платформе Win32.pdf
Добавлен: 01.04.2023
Просмотров: 60
Скачиваний: 2
Описание программы клиента
При запуске программы клиента отображается окно, в котором необходимо заполнить два поля. Первое из них нужно для соединения с сервером и требует правильного заполнения, второе нужно для инициализации пользователя и может быть заполнено по усмотрению самого пользователя (Рис. 2).
Рис. 2
Помимо этого, в этом же окне присутствует CheckBox, который восстанавливает значение IP адреса, введенного в прошлый раз, тем самым облегчая ввод. (Рис. 3)
Рис. 3
Ниже приведена реализация данной функции:
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
try
{
if (checkBox1.Checked)
{
var sr = new StreamReader(@"Chat_Info/nastroyki.txt");
string buffer = sr.ReadToEnd();
sr.Close();
string[] ip = buffer.Split(':');
textBox1.Text = ip[0];
checkBox1.Enabled = false;
}
}
catch (Exception ex)
{
MessageBox.Show("Ошибка: " + ex.Message);
}
}
Так же в правом нижнем углу есть изображение, в виде знака вопроса, при нажатии на которое отображается инструкция для пользователя. (Рис. 4)
Рис. 4
В нижней части окна находится кнопка «Войти в чат!», при нажатии на которую закрывается данное окно и открывается новое, в котором происходит подключении к серверу по заданным ранее настройкам.
private void button1_Click(object sender, EventArgs e)
{
if (textBox1.Text != " " && textBox1.Text != "" && textBox2.Text != " " && textBox2.Text != "")
{
try
{
DirectoryInfo data = new DirectoryInfo("Chat_Info");
data.Create();
var sw = new StreamWriter(@"Chat_Info/nastroyki.txt");
sw.WriteLine(textBox1.Text + ":" + textBox2.Text);
sw.Close();
this.Hide();
Form1 form = new Form1();
form.Show();
}
catch (Exception ex)
{
MessageBox.Show("Ошибка: " + ex.Message);
}
}
else MessageBox.Show("Заполните все поля!");
}
При этом, если оба или одно из полей осталось пустым, на экран будет выведено соответствующее сообщение. (Рис. 5)
Рис. 5
Если IP адрес сервера был введён корректно, то в окне приложения зелёным цветом будет отображаться именно этот IP адрес (Рис. 6).
Рис. 6
В противном случае, будет выведена надпись об отсутствии настроек и появится кнопка, с помощью которой можно заново ввести настройки (Рис. 7).
Рис. 7
Если выведена зелёная надпись IP адреса и в листинге чата написано «Connect…», соответственно пользователь успешно подключился и может начать писать своё сообщение в нижнем поле для ввода текста. Для отправки сообщения нужно нажать кнопку «Отправить» либо нажать кнопку «Enter» на клавиатуре.
private void button1_Click_1(object sender, EventArgs e)
{
SendMessage("\n" + nik + ": " + textBox2.Text + "**8");
textBox2.Clear();
}
В Меню приложения есть кнопка «Автор», при нажатии на которую выводится информация о разработчике приложения (Рис. 8).
Рис. 8
Для выхода из чата нужно выбрать пункт из меню «Выход», после чего в листинге чата, пользователь будет проинформирован о том, что он вышел из чата (Рис. 9). При этом, если он выбрал этот пункт меню до того, как вошел в чат, то также будет выведено соответствующее сообщение. (Рис. 7)
Рис. 9
private void выходToolStripMenuItem_Click_1(object sender, EventArgs e)
{
if (th != null) th.Abort();
if (Client != null)
{
Client.Close();
textBox2.Enabled = false;
button1.Enabled = false;
label5.Enabled = false;
listBox1.Items.Add("Вы вышли из чата...");
}
else listBox1.Items.Add("Вы ещё не зашли в чат!");
}
Функция отправки сообщения серверу выглядит следующим образом:
void SendMessage(string message)
{
if (message != " " && message != "")
{
byte[] buffer = new byte[1024];
buffer = Encoding.UTF8.GetBytes(message);
Client.Send(buffer);
}
}
Функция приёма сообщений от сервера:
void RegOfMessage()
{
byte[] buffer = new byte[1024];
for (int i = 0; i < buffer.Length; i++)
{ buffer[i] = 0; }
for (; ; )
{
try
{
Client.Receive(buffer);
string messege = Encoding.UTF8.GetString(buffer);
int count = messege.IndexOf("**8");
if (count == -1)
{ continue; }
string Clean_Mes = "";
for (int i = 0; i < count; i++)
{ Clean_Mes += messege[i]; }
for (int i = 0; i < buffer.Length; i++)
{ buffer[i] = 0; }
this.Invoke((MethodInvoker)delegate()
{ listBox1.Items.Add(Clean_Mes); });
}
catch (Exception ex) { }
}
}
Подключение клиента реализуется следующим образом:
Client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
if (ip != null)
{
Client.Connect(ip, port);
th = new Thread(delegate() { RegOfMessage(); });
th.Start();
}
Приложение
My_Server.cpp:
#pragma comment(lib,"Ws2_32.lib")
#include <WinSock2.h>
#include <iostream>
#include <WS2tcpip.h>
SOCKET Connect;
SOCKET* Connections;
SOCKET Listen;
int ClientCount = 0;
void SendMessageToClient(int ID)
{
char* buffer = new char[1024];
for (;; Sleep(100))
{
memset(buffer, 0, sizeof(buffer));
if (recv(Connections[ID], buffer, 1024, NULL))
{
printf("%s", buffer);
for (int i = 0; i <= ClientCount; i++)
{
send(Connections[i], buffer, strlen(buffer), NULL);
}
}
}
free(buffer);
}
int main()
{
setlocale(LC_ALL, "russian");
WSAData data;
WORD version = MAKEWORD(2, 2);
int res = WSAStartup(version, &data);
if (res != 0)
{
return 0;
}
struct addrinfo server;
struct addrinfo * result;
Connections = (SOCKET*)calloc(64, sizeof(SOCKET));
ZeroMemory(&server, sizeof(server));
server.ai_family = AF_INET;
server.ai_flags = AI_PASSIVE;
server.ai_socktype = SOCK_STREAM;
server.ai_protocol = IPPROTO_TCP;
getaddrinfo(NULL, "8888", &server, &result);
Listen = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
bind(Listen, result->ai_addr, result->ai_addrlen);
listen(Listen, SOMAXCONN);
freeaddrinfo(result);
char conect[] = "Connect...**8";
char kol[] = "All users: ";
printf("Server connect...\n");
printf(kol);
printf("%d", ClientCount);
for (;; Sleep(100))
{
if (Connect = accept(Listen, NULL, NULL))
{
printf("\nClient connect...\n");
printf(kol);
printf("%d", ClientCount + 1);
Connections[ClientCount] = Connect;
send(Connections[ClientCount], conect, strlen(conect), NULL);
ClientCount++;
CreateThread(NULL, NULL, (PTHREAD_START_ROUTINE)SendMessageToClient, (LPVOID)(ClientCount - 1), NULL, NULL);
}
}
return 1;
}
MyChat_Client
Form1.cs:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net.Sockets;
using System.IO;
using System.Net;
using System.Threading;
namespace MyChat_Client
{
public partial class Form1 : Form
{
static private Socket Client;
private IPAddress ip = null;
private int port = 8888;
private string nik;
private Thread th;
public Form1()
{
InitializeComponent();
textBox2.Enabled = false;
button1.Enabled = false;
label5.Enabled = false;
try
{
var sr = new StreamReader(@"Chat_Info/nastroyki.txt");
string buffer = sr.ReadToEnd();
sr.Close();
string[] info = buffer.Split(':');
ip = IPAddress.Parse(info[0]);
nik = info[1];
label4.ForeColor = Color.Green;
label4.Text = " Подключение по IP сервера: " + info[0];
Client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
if (ip != null)
{
Client.Connect(ip, port);
th = new Thread(delegate() { RegOfMessage(); });
th.Start();
button1.Enabled = true;
textBox2.Enabled = true;
label5.Enabled = true;
listBox1.Items.Add(nik + " присоединился!");
}
}
catch (Exception ex)
{
label4.ForeColor = Color.Red;
label4.Text = "Настройки не найдены\nВведите заново!";
button2.Visible = true;
}
}
void SendMessage(string message)
{
if (message != " " && message != "")
{
byte[] buffer = new byte[1024];
buffer = Encoding.UTF8.GetBytes(message);
Client.Send(buffer);
}
}
void RegOfMessage()
{
byte[] buffer = new byte[1024];
for (int i = 0; i < buffer.Length; i++)
{ buffer[i] = 0; }
for (; ; )
{
try
{
Client.Receive(buffer);
string messege = Encoding.UTF8.GetString(buffer);
int count = messege.IndexOf("**8");
if (count == -1)
{ continue; }
string Clean_Mes = "";
for (int i = 0; i < count; i++)
{ Clean_Mes += messege[i]; }
for (int i = 0; i < buffer.Length; i++)
{
buffer[i] = 0;
}
this.Invoke((MethodInvoker)delegate()
{
listBox1.Items.Add(Clean_Mes);
});
}
catch (Exception ex) { }
}
}
private void авторToolStripMenuItem_Click_1(object sender, EventArgs e)
{
MessageBox.Show("Булычёв Вячеслав \n ДБО - 481 \n 2015г");
}
private void button1_Click_1(object sender, EventArgs e)
{
SendMessage("\n" + nik + ": " + textBox2.Text + "**8");
textBox2.Clear();
}
private void textBox2_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
SendMessage("\n" + nik + ": " + textBox2.Text + "**8");
textBox2.Clear();
}?
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button2_Click(object sender, EventArgs e)
{
this.Hide();
Form3 form = new Form3();
form.Show();
}
private void выходToolStripMenuItem_Click_1(object sender, EventArgs e)
{
if (th != null) th.Abort();
if (Client != null)
{
Client.Close();
textBox2.Enabled = false;
button1.Enabled = false;
label5.Enabled = false;
listBox1.Items.Add("Вы вышли из чата...");
}
else listBox1.Items.Add("Вы ещё не зашли в чат!");
}
}
}
Form3.cs:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;