Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Курсовая работа-1.docx
Скачиваний:
35
Добавлен:
10.03.2021
Размер:
143.95 Кб
Скачать

Задание на курсовую работу

Разработать многозадачное приложение, выполняющее получение, сбор и вывод системной информации в соответствии с вариантом задания:

вар.

Способ

коммуникации

Процесс 1

определяет и передает

Процесс 2

определяет и передает

3

сокеты

- текущее местное время

- продолжительность текущего сеанса

работы

- приоритеты клиентского и серверных

процессов;

- дельта-приоритеты их потоков

Разработка и описание алгоритма

Сервер ожидает входящее соединение на порту 15000 или 1500. После получения соединения он производит вычисления и получает определенные данные и отправляет их клиенту. При запросе соединения мы начинаем передавать данные на тот порт, который передает клиент при коннекте, это позволяет нам передавать данные конкретному клиенту, а не всем сразу.

Клиент соединяется с сервером на порту 15000 или 15001, после успешного подключения он получает все необходимые данные из сервера и разрывает соединение.

Описание cтруктуры программы

В серверной части приложений есть класс SocketServer для работы с сокетами, где происходит основная часть полезной работы, то есть получение требуемых заданием данных и формируется сообщение и соответственно оно отправляется клиенту. В классе основной функцией является Listening, в ней происходят расчеты данных и формирование сообщения, а отправка идет с помощью функций SendAll и Send. В последней функции происходит побайтовая отправка сообщения, в котором хранятся необходимые данные. В конце сообщения всегда должно присутствовать слово end, сигнализирующей об окончании сообщения, чтобы клиент перестал принимать данные и закрыл соединение.

В клиентской части существует класс SocketClient, где происходит подключение к сокету сервера, а также получение сообщений.

Руководство пользователя.

Сервер обладает кнопкой выход. При нажатии этой кнопки закрывается соединение и освобождаются все ресурсы процесса. Соединение, обработка и посыл данных выполняется в «тихом» режиме без контроля пользователем.

Клиент имеет 4 кнопки. Во – первых, это «Получить данные с первого сервера» – при нажатии на кнопку происхдоитесли сервер доступен, тогда мы устанавливаем с ним соединение и получаем данные. В случае если подключение не установлено, получаем сообщение об этом. Во – вторых, это «Получить данные со второго сервера» аналогично предыдущей кнопке. В-третьих, «Очистить» – очищает список сообщений в левой части экрана. В – четвертых, «Выход» – кнопка осуществляет выход из программы.

Результаты работы программ.

Результат проведенной работы представлен на рисунке 1.

Рисунок 1- результат клиент-серверного взаимодействия

Приложение

Код для первого сервера:

using System;

using System.Collections.Generic;

using System.Text;

using System.Windows.Forms;

using System.Net.Sockets;

using System.Threading;

using System.Net;

namespace Server1

{

public partial class Form1: Form

{

SocketServer server;

public Form1()

{

InitializeComponent();

// получение локального IP адреса компьютера

string MyIp = "";

foreach (IPAddress ip in Dns.GetHostByName(Dns.GetHostName()).AddressList) {

MyIp = ip.ToString();

break;

}

server = new SocketServer(MyIp, 15000);

server.Start();

Thread list = new Thread(List);

list.IsBackground = true;

list.Start();

}

// кнопка выхода

private void btnExit(object sender, EventArgs e) {

server.Dispose();

this.Dispose();

Application.Exit();

}

// добавление сведений о доставке сообщения, а то есть указывается адресат

private void List() {

for (; ; Thread.Sleep(200))

if (server.ClientList.Count != lbx_clientList.Items.Count) {

lbx_clientList.Invoke(new MethodInvoker(delegate {

lbx_clientList.Items.Clear();

}));

for (int i = 0; i < server.ClientList.Count; i++)

lbx_clientList.Invoke(new MethodInvoker(delegate {

lbx_clientList.Items.Add("Доставлено по адресу: " + server.ClientList[i]);

}));

}

}

}

class SocketServer

{

public Socket server;

private IPEndPoint ip;

private List<Thread> thread_list; // список потоков

private int max_conn;

public List<string> ClientList = new List<string>();

// создание и инициализация сокета

public SocketServer(string ip, Int32 port)

{

this.max_conn = 2;

this.thread_list = new List<Thread>();

this.ip = new IPEndPoint(IPAddress.Parse(ip), port);

this.server = new Socket(this.ip.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

this.server.Bind(this.ip); // cвязываение сокет с конечной локальной точкой

this.server.Listen(this.max_conn); // макс кол-во слушателей

}

// запуск потока

public void Start() {

for (int i = 0; i < this.max_conn; i++) {

Thread th = new Thread(Listening);

th.Start();

thread_list.Add(th);

}

}

// закрытие сокета

public void Dispose() {

foreach (Thread th in thread_list) {

th.Interrupt();

}

server.Close();

}

// прослушивание

// здесь идет расчет текущего местного времени и времени работы компьютера, а также запись в файл и отправка их.

private void Listening() {

while (true) {

try {

using (Socket client = this.server.Accept()) {

this.ClientList.Add(client.RemoteEndPoint.ToString());

client.Blocking = true;

if (client.Connected) {

List<string> message = new List<string>();

message.Add("Текущее местное время: " + System.DateTime.Now.ToLongTimeString());

String strResult = String.Empty;

strResult += Convert.ToString(Environment.TickCount / 86400000) + " дней, ";

strResult += Convert.ToString(Environment.TickCount / 3600000 % 24) + " часов, ";

strResult += Convert.ToString(Environment.TickCount / 120000 % 60) + " минут, ";

strResult += Convert.ToString(Environment.TickCount / 1000 % 60) + " секунд.";

message.Add("Время работы компьютера: " + strResult);

message.Add("[end]");

SendAll(client, message);

}

}

} catch (SocketException ex) {

}

}

}

// отправление всего сообщения

public void SendAll(Socket handler, List<string> message) {

for (int i = 0; i < message.Count;) {

Send(message[i], handler);

message.RemoveAt(i);

Thread.Sleep(5);

}

}

// отправка указанного кол-ва байтов по сокету

public void Send(string message, Socket handler) {

byte[] tosend = Encoding.UTF8.GetBytes(message);

try {

handler.Send(tosend, 0, tosend.Length, SocketFlags.None);

} catch {

}

}

}

}

Код для второго сервера:

using System;

using System.Collections.Generic;

using System.Text;

using System.Windows.Forms;

using System.Net.Sockets;

using System.Threading;

using System.Net;

using System.Diagnostics;

namespace server2

{

public partial class Form1 : Form

{

SocketServer server;

public Form1()

{

InitializeComponent();

string MyIp = "";

foreach (IPAddress ip in Dns.GetHostByName(Dns.GetHostName()).AddressList)

{

MyIp = ip.ToString();

break;

}

server = new SocketServer(MyIp, 15001);

server.Start();

Thread list = new Thread(List);

list.IsBackground = true;

list.Start();

}

// кнопка выхода

private void btnExit(object sender, EventArgs e)

{

server.Dispose();

this.Dispose();

Application.Exit();

}

// добавление сведений о доставке сообщения, а то есть указывается адресат

private void List() {

for (; ; Thread.Sleep(200))

if (server.ClientList.Count != lbx_clientList.Items.Count)

{

lbx_clientList.Invoke(new MethodInvoker(delegate {

lbx_clientList.Items.Clear();

}));

for (int i = 0; i < server.ClientList.Count; i++)

lbx_clientList.Invoke(new MethodInvoker(delegate {

lbx_clientList.Items.Add("Доставлено по адресу: " + server.ClientList[i]);

}));

}

}

}

class SocketServer

{

public Socket server;

private IPEndPoint ip;

private List<Thread> thread_list;

private int max_conn;

public List<string> ClientList = new List<string>();

public SocketServer(string ip, Int32 port)

{

this.max_conn = 2;

this.thread_list = new List<Thread>();

this.ip = new IPEndPoint(IPAddress.Parse(ip), port);

this.server = new Socket(this.ip.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

this.server.Bind(this.ip); this.server.Listen(this.max_conn);

}

// запуск потока

public void Start()

{

for (int i = 0; i < this.max_conn; i++)

{

Thread th = new Thread(Listening);

th.Start();

thread_list.Add(th);

}

}

// освобождение сокета

public void Dispose()

{

foreach (Thread th in thread_list)

{

th.Interrupt();

}

server.Close();

}

// обработка приоритетов

private string Priority(int number)

{

switch (number)

{

case 4: { return ("4 - Приоритет маленький"); }

case 6: { return ("6 - Приоритет ниже нормального"); }

case 8: { return ("8 - Приоритет нормальный"); }

case 10: { return ("10 - Приоритет выше нормального"); }

case 13: { return ("13 - Приоритет высокий"); }

case 24: { return ("24 - Приоритет реального времени"); }

default: { return ("Приоритет неизвестен"); }

}

}

// подключение к сокету и отправка данных и приоритетах потоков и процессов.

private void Listening()

{

while (true)

{

try

{

using (Socket client = this.server.Accept())

{

this.ClientList.Add(client.RemoteEndPoint.ToString());

client.Blocking = true;

if (client.Connected)

{

// получение данных о приоритетах потоков процесса сервера

List<string> message = new List<string>();

Process[] serverProc = Process.GetProcessesByName("server2");

for (int i = 0; i < serverProc.Length; i++)

{

ProcessThreadCollection ListServer = serverProc[i].Threads;

message.Add("Сервер " + ": " + Priority(serverProc[i].BasePriority));

message.Add("Количество потоков в сервере - " + ListServer.Count + ".");

for (int j = 0; j < ListServer.Count; j++)

message.Add((j+1) + ". Поток №" + ListServer[j].Id + ": " + Priority(ListServer[j].BasePriority));

}

// получение данных о приоритетах потоков процесса клиента

Process[] clientProc = Process.GetProcessesByName("kursovay");

for (int i = 0; i < clientProc.Length; i++)

{

ProcessThreadCollection ListServer = clientProc[i].Threads;

message.Add("Клиент " + ": " + Priority(clientProc[i].BasePriority));

message.Add("Количество потоков в клиенте - " + ListServer.Count + ".");

for (int j = 0; j < ListServer.Count; j++)

message.Add((j+1) + ". Поток №" + ListServer[j].Id + ": " + Priority(ListServer[j].BasePriority));

}

message.Add("[end]");

SendAll(client, message);

}

}

}

catch (SocketException ex)

{

}

}

}

// отправка всех сообщений

public void SendAll(Socket handler, List<string> message)

{

for (int i = 0; i < message.Count;)

{

Send(message[i], handler);

message.RemoveAt(i);

Thread.Sleep(5);

}

}

// побайтовая отправка сообщения

public void Send(string message, Socket handler)

{

byte[] tosend = Encoding.UTF8.GetBytes(message);

try

{

handler.Send(tosend, 0, tosend.Length, SocketFlags.None);

}

catch

{

}

}

}

}

Код клиента:

using System;

using System.Collections.Generic;

using System.Text;

using System.Windows.Forms;

using System.Net.Sockets;

using System.Threading;

using System.Net;

namespace kursovay

{

public partial class Form1 : Form

{

int port;

static SocketClient client;

public Form1()

{

InitializeComponent();

string MyIp = "";

foreach (IPAddress ip in Dns.GetHostByName(Dns.GetHostName()).AddressList)

{

MyIp = ip.ToString();

break;

}

label1.Text = "Текущий ip: " + MyIp.ToString();

}

// получение локального Ip адреса и создание сокета

private void connection()

{

string MyIp = "";

foreach (IPAddress ip in Dns.GetHostByName(Dns.GetHostName()).AddressList)

{

MyIp = ip.ToString();

break;

}

client = new SocketClient(MyIp, this.port);

if (client.Connect())

{

lbx_message.Invoke(new MethodInvoker(delegate {

lbx_message.Items.Add("Соединение с сервером установлено!");

lbx_message.Items.Add("Ожидайте...");

}));

lbx_message.Invoke(new MethodInvoker(delegate {

lbx_message.Items.Add("Полученные даннные:");

}));

Status();

} else

{

lbx_message.Invoke(new MethodInvoker(delegate {

lbx_message.Items.Add("Невозможно установить соединение с сервером!");

lbx_message.Items.Add("Попробуйте позже!");

}));

}

}

// обращение к серверу №1

private void btnServer1(object sender, EventArgs e) {

port = 15000;

Thread connect = new Thread(connection);

connect.Start();

connect.IsBackground = true;

}

// получение данных с сокета

private void Status()

{

for (; ; )

{

client.Receive();

try

{

// если получение слово указывающее на конец строки завершаем цикл приема сообщения

if (client.ReceiveMessage[client.ReceiveMessage.Count - 1] == "[end]")

break;

}

catch

{

}

}

for (int i = 0; i < client.ReceiveMessage.Count;)

{

if (client.ReceiveMessage[i] != "[end]")

lbx_message.Invoke(new MethodInvoker(delegate {

lbx_message.Items.Add(client.ReceiveMessage[i]);

}));

client.ReceiveMessage.RemoveAt(i);

}

}

// обращение к серверу №2

private void bthServer2(object sender, EventArgs e)

{

this.port = 15001;

Thread connect = new Thread(connection);

connect.Start();

connect.IsBackground = true;

}

// очищение списка полученных данных

private void btnClear_Click(object sender, EventArgs e)

{

lbx_message.Items.Clear();

}

//закрытие приложения

private void btnExit_Click(object sender, EventArgs e)

{

Application.Exit();

}

private void Form1_Load(object sender, EventArgs e)

{

}

}

class SocketClient

{

public Socket client;

private IPEndPoint ip;

public List<string> SendMessage = new List<string>();

public List<string> ReceiveMessage = new List<string>();

public SocketClient(string ip, Int32 port)

{

this.ip = new IPEndPoint(IPAddress.Parse(ip), port);

this.client = new Socket(this.ip.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

}

public bool Connect()

{

try

{

this.client.Connect(this.ip);

return true;

}

catch

{

return false;

}

}

// получение данных из сокета

public void Receive()

{

string message = String.Empty;

byte[] GetBytes = new byte[1024];

try

{

int b = client.Receive(GetBytes);

message = Encoding.UTF8.GetString(GetBytes, 0, b);

if (message != "")

this.ReceiveMessage.Add(message);

}

catch

{

}

}

// осуществляет отключение

public void Disconnect()

{

this.client.Disconnect(false);

}

}

}