отчет. Жуманзаров_отчет1. Отчет по лабораторной работе 1 Разработка сервера доступа к данным по протоколу tcpIP
Скачать 69.79 Kb.
|
МИНОБРНАУКИ РОССИИ федеральное государственное бюджетное образовательное учреждение высшего образования «Московский государственный технологический университет «СТАНКИН» (ФГБОУ ВО «МГТУ «СТАНКИН»)
Дисциплина" Средства мониторинга в системах управления" ОТЧЕТ ПО ЛАБОРАТОРНОЙ РАБОТЕ №1 «Разработка сервера доступа к данным по протоколу TCP/IP»
Москва 2022 г. ОглавлениеОбщее задание 2 Коды программ 3 Запуск проекта 9 Индивидуальное задание 10 Общее заданиеРазработать программное приложение – сетевой сервер, способный принимать входящие подключения по протоколу TCP/IP отвечать на принимаемые по сети запросы. Коды программКласс CommunicationServer.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using System.Net.Sockets; using System.Threading; using System.Diagnostics; namespace TCPserver { public delegate void ServerExitDelegate(); public delegate bool RequestReceivedDelegate(int ClientGUID, byte[] Request, out byte[] Reply); public delegate void ClientDisconnectedDelegate(int ClientGUID); class CommunicationServer { private int ListenSocketPort; private Socket IncomingConnectionSocket; private Thread IncomingConnectionThread; private CommunicationServerClient[] CommunicationClients; //декларация callback-функций public ServerExitDelegate OnServerExitCallback; public RequestReceivedDelegate OnRequestRecievedCallback; public ClientDisconnectedDelegate OnClientDisconnectedCallback; public CommunicationServer() { OnServerExitCallback = null; OnRequestRecievedCallback = null; OnClientDisconnectedCallback = null; } public bool StartServer(int PortNo) { ListenSocketPort = PortNo; CommunicationClients = new CommunicationServerClient[10]; if (CommunicationClients == null) return false; for (int i = 0; i < CommunicationClients.Length; i++) { CommunicationClients[i] = new CommunicationServerClient(); if (CommunicationClients[i] == null) { StopServer(); return false; } } IncomingConnectionThread = new Thread(new ThreadStart(IncomingConnectionThreadProc)); IncomingConnectionThread.Start(); return true; } public void StopServer() { if (IncomingConnectionThread != null) { IncomingConnectionThread.Abort(); } if (IncomingConnectionSocket != null) { IncomingConnectionSocket.Close(); } if (CommunicationClients != null) { for (int i = 0; i < CommunicationClients.Length; i++) { if (CommunicationClients[i] != null) { CommunicationClients[i].Disconnect(); CommunicationClients[i] = null; } } } if (OnServerExitCallback != null) { OnServerExitCallback(); } } private void IncomingConnectionThreadProc() { IncomingConnectionSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); if (IncomingConnectionSocket == null) { Trace.TraceError("Неудалосьсоздать IncomingConnectionSocket"); OnServerExit(); return; } try { IPEndPoint ep = new IPEndPoint(IPAddress.Any, ListenSocketPort); IncomingConnectionSocket.Bind(ep); } catch (Exception ex) { Trace.TraceError("Неудалосьсделать Bind() для IncomingConnectionSocket"); Trace.TraceError(ex.ToString()); OnServerExit(); return; } try { IncomingConnectionSocket.Listen(5); } catch (Exception ex) { Trace.TraceError("Неудалосьсделать Listen() для IncomingConnectionSocket"); Trace.TraceError(ex.ToString()); OnServerExit(); return; } while (true) { Socket newConnectionSocket = null; try { Trace.TraceInformation(@"Ожидаем входящего подключения"); newConnectionSocket = IncomingConnectionSocket.Accept(); } catch (Exception ex) { Trace.TraceError("Неудалосьсделать Accept() для IncomingConnectionSocket"); Trace.TraceError(ex.ToString()); OnServerExit(); return; } if (newConnectionSocket != null) { OnClientConnected(newConnectionSocket); } } } private void OnClientConnected(Socket ClientSocket) { int ClientGUID = GetGUIDForClient(); if (ClientGUID == -1) { CommunicationClients[0].FinishConnect(ClientSocket, ClientGUID); CommunicationClients[0].Disconnect(); } CommunicationServerClient client = CommunicationClients[ClientGUID]; if (client == null) return; int result = client.FinishConnect(ClientSocket, ClientGUID); if (result == 0) { client.OnSyncRequestReceived = OnRequestRecieved; client.OnClientDisconnected = OnClientDisconnected; Trace.TraceInformation(@"Клиентприконнектился. ClientGIUD = {0}. Всего клиентов соединено {1}.", ClientGUID, @"n/a"); } else { client.Disconnect(); Trace.TraceInformation(@"Коннектнеудался. ClientGIUD = {0}. Всего клиентов соединено {1}.", ClientGUID, @"n/a"); } } private void OnClientDisconnected(int ClientGUID) { if (OnClientDisconnectedCallback != null) OnClientDisconnectedCallback(ClientGUID); CommunicationServerClient client = CommunicationClients[ClientGUID]; if (client != null) { Trace.TraceInformation(@"Клиентотконнектился. ClientGIUD = {0}. Всегоклиентовсоединено {1}.", ClientGUID, @"xz"); client.Disconnect(); } } private bool OnRequestRecieved(int ClientGUID, byte[] Request, out byte[] Reply) { if (OnRequestRecievedCallback != null) { return OnRequestRecievedCallback(ClientGUID, Request, out Reply); } Reply = null; return false; } private void OnServerExit() { Trace.TraceError(@"OnServerExit() - критическая ошибка"); if (OnServerExitCallback != null) OnServerExitCallback(); } private int GetGUIDForClient() { for (int i = 1; i < CommunicationClients.Length; i++) { if (CommunicationClients[i] != null) { if (CommunicationClients[i].ClientGuid == -1) return i; } } return -1; } } } Класс CommunicationServerClient.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net.Sockets; using System.Threading; using System.Diagnostics; namespace TCPserver { class CommunicationServerClient { private Socket SyncSocket; private Thread SyncSocketThread; private int _ClientGUID = 0; public int ClientGuid { get { return _ClientGUID; } } public RequestReceivedDelegate OnSyncRequestReceived; public ClientDisconnectedDelegate OnClientDisconnected; public CommunicationServerClient() { _ClientGUID = -1; OnSyncRequestReceived = null; OnClientDisconnected = null; } private void SyncSocketThreadProc() { //Отправляем нотификацию, что сервер готов try { int BytesSend = SyncSocket.Send(BitConverter.GetBytes(_ClientGUID)); } catch (Exception ex) { Trace.TraceError(@"Не получилось отправить нотификацию, что сервер готов"); Trace.TraceError(ex.ToString()); OnClientExit(); return; } byte[] RecieveBuffer = new byte[8192]; byte[] SendBuffer = new byte[8192]; while (true) { int BytesReceived = 0; //Ждемзапроса try { BytesReceived = SyncSocket.Receive(RecieveBuffer, 8192, SocketFlags.None); } catch (Exception ex) { Trace.TraceError(@"Ошибка при получении данных по синхронному каналу"); Trace.TraceError(ex.ToString()); OnClientExit(); return; } //Это, как ни странно, свидетельствует о дисконнекте if (BytesReceived <= 0) { OnClientExit(); return; } if ((BytesReceived > 0) && (OnSyncRequestReceived != null)) { byte[] Reply = null; byte[] Request = new byte[BytesReceived]; Array.Copy(RecieveBuffer, Request, BytesReceived); bool bReply = OnSyncRequestReceived(_ClientGUID, Request, out Reply); if ((bReply == true) && (Reply != null)) { //Отправляемответ try { int BytesSend = SyncSocket.Send(Reply); } catch (Exception ex) { Trace.TraceError(@"Не получилось отправить ответ на синхронный запрос"); Trace.TraceError(ex.ToString()); OnClientExit(); return; } } } } } public void Disconnect() { _ClientGUID = -1; OnSyncRequestReceived = null; OnClientDisconnected = null; if (SyncSocket != null) { SyncSocket.Close(); } if (SyncSocketThread != null) { SyncSocketThread.Abort(); } } private void OnClientExit() { if (OnClientDisconnected != null) OnClientDisconnected(_ClientGUID); Disconnect(); } public int FinishConnect(Socket ClientSocket, int ConnectionGUID) { SyncSocket = ClientSocket; _ClientGUID = ConnectionGUID; //Отправляемидентификаторсоединения try { int BytesSend = SyncSocket.Send(BitConverter.GetBytes(_ClientGUID)); } catch (Exception ex) { Trace.TraceError(@"Неполучилосьотправить ClientGUID"); Trace.TraceError(ex.ToString()); OnClientExit(); return -1; } if (_ClientGUID == -1) return -1; //Создаемпотоксинхронногоканала SyncSocketThread = new Thread(new ThreadStart(SyncSocketThreadProc)); SyncSocketThread.Start(); return 0; } } } Код для формы 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; namespace TCPserver { public partial class Form1 : Form { private CommunicationServer Server; public Form1() { InitializeComponent(); Server = new CommunicationServer(); } private void buttonStartServer_Click_1(object sender, EventArgs e) { if (Server.StartServer(22222) == false) { MessageBox.Show(@"Неудалосьстартоватьсервер", @"Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); } else { Server.OnServerExitCallback = OnServerExit; Server.OnRequestRecievedCallback = OnRequestReceived; } } private void buttonStopServer_Click_1(object sender, EventArgs e) { Server.StopServer(); } private void OnServerExit() { } private bool OnRequestReceived(int ClientGUID, byte[] Request, out byte[] Reply) { Reply = new byte[Request.Length]; Array.Copy(Request, Reply, Request.Length); return true; } } } Запуск проектаПри запуске проекта видим, что при нажатии кнопки “Start Server” в консоли вывода Visual Studio появляется сообщение TCPServer.vshost.exe Information: 0 : Ожидаем входящего подключения, Следовательно сервер успешно стартует. Рис.1. Результат запуска Индивидуальное заданиеРеализовать в коммуникационном сервере запрос, позволяющий получать из сервера ФИО студента, выполнившего лабораторную работу. using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net.Sockets; using System.Threading; using System.Diagnostics; namespace TCPserver { class CommunicationServerClient { private Socket SyncSocket; private Thread SyncSocketThread; private int _ClientGUID = 0; public int ClientGuid { get { return _ClientGUID; } } public RequestReceivedDelegate OnSyncRequestReceived; public ClientDisconnectedDelegate OnClientDisconnected; public CommunicationServerClient() { _ClientGUID = -1; OnSyncRequestReceived = null; OnClientDisconnected = null; } private void SyncSocketThreadProc() { //Отправляем нотификацию, что сервер готов try { int BytesSend = SyncSocket.Send(BitConverter.GetBytes(_ClientGUID)); } catch (Exception ex) { Trace.TraceError(@"Не получилось отправить нотификацию, что сервер готов"); Trace.TraceError(ex.ToString()); OnClientExit(); return; } byte[] RecieveBuffer = new byte[8192]; byte[] SendBuffer = new byte[8192]; while (true) { int BytesReceived = 0; //Ждемзапроса try { BytesReceived = SyncSocket.Receive(RecieveBuffer, 8192, SocketFlags.None); } catch (Exception ex) { Trace.TraceError(@"Ошибка при получении данных по синхронному каналу"); Trace.TraceError(ex.ToString()); OnClientExit(); return; } //Это, как ни странно, свидетельствует о дисконнекте if (BytesReceived <= 0) { OnClientExit(); return; } if ((BytesReceived > 0) && (OnSyncRequestReceived != null)) { byte[] Reply = null; byte[] Request = new byte[BytesReceived]; Array.Copy(RecieveBuffer, Request, BytesReceived); string student = "Щебров Павел Дмитриевич"; byte[] std = Encoding.UTF8.GetBytes(student); bool bReply = OnSyncRequestReceived(_ClientGUID, Request, out Reply); if ((bReply == true) && (Reply != null)) { //Отправляемответ try { int BytesSend = SyncSocket.Send(std); } catch (Exception ex) { Trace.TraceError(@"Не получилось отправить ответ на синхронный запрос"); Trace.TraceError(ex.ToString()); OnClientExit(); return; } } } } } public void Disconnect() { _ClientGUID = -1; OnSyncRequestReceived = null; OnClientDisconnected = null; if (SyncSocket != null) { SyncSocket.Close(); } if (SyncSocketThread != null) { SyncSocketThread.Abort(); } } private void OnClientExit() { if (OnClientDisconnected != null) OnClientDisconnected(_ClientGUID); Disconnect(); } public int FinishConnect(Socket ClientSocket, int ConnectionGUID) { SyncSocket = ClientSocket; _ClientGUID = ConnectionGUID; //Отправляемидентификаторсоединения try { int BytesSend = SyncSocket.Send(BitConverter.GetBytes(_ClientGUID)); } catch (Exception ex) { Trace.TraceError(@"Неполучилосьотправить ClientGUID"); Trace.TraceError(ex.ToString()); OnClientExit(); return -1; } if (_ClientGUID == -1) return -1; //Создаемпотоксинхронногоканала SyncSocketThread = new Thread(new ThreadStart(SyncSocketThreadProc)); SyncSocketThread.Start(); return 0; } } } |