Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
лр3_Удаленное взаимодействие_Сокеты.doc
Скачиваний:
10
Добавлен:
20.08.2019
Размер:
3.66 Mб
Скачать

1.5. Клиент-серверное взаимодействие без установки соединения.

Передача информации на основе соединения напоминает использование системы телефонной связи, когда пользователь набирает номер и соединяется с телефоном абонента. Система поддерживает соединение в течение телефонного вызова, независимо от того, разговаривают абоненты или нет.

В противоположность этому передача без установки соединения с помощью дэйтаграмм больше напоминает метод пересылки и доставки почты. При передаче без установления соединения информация объединяется в пакеты, называемые дэйтаграммами, которые можно сравнить с отправленными письмами. Если большое сообщение не помещается в один конверт, то оно разбивается на части и помещается в отдельные последовательно пронумерованные конверты. Все письма отправляются одновременно. Они могут доходить до адресата в указанном порядке, без соблюдения порядка, либо не доходить вообще. Перед интерпретацией содержимого сообщения адресат упорядочивает все его части. Если сообщение не очень большое и может разместиться в одном конверте, то задача упорядочения снимается, но при этом остается вариант, что сообщение никогда не дойдет до адресата. Для передачи информации независимо от соединения в С# предусмотрен класс UdpClient. Подобно классам TcpListener и TcpClient, класс UdpClient использует методы класса Socket. Методы Send и Receive класса UdpClient предназначены для передачи данных с помощью методов Socket.SendTo() и для считывания данных с помощью метода Socket.ReceiveFrom().

1.5.1. Пример организация взаимодействия.

Рассмотрим пример использования дэйтаграмм для передачи пакетов информации между приложениями клиента и сервера. В приложении клиента пользователь вводит сообщение в текстовое поле и нажимает на клавишу <Enter>. Клиент преобразует сообщение в массив байтов и отправляет его в серверное приложение. Сервер получает пакет, отображает его информацию и возвращает пакет обратно клиенту. При получении пакета клиент отображает содержащуюся в нем информацию. В данном примере реализации классов клиента и сервера сходны.

1.5.1.1. Серверная часть.

// Настройка серверного приложения, принимающего пакеты информации от клиента и

// передающего пакеты информации клиенту

using System;

using System.Drawing;

using System.Collection;

using System.ComponentModel;

using System.Windows.Forms;

using System.Data;

using System.Net;

using System.Net.Sockets;

using System.Threading;

// Создание сервера UDP

public class Server : System.Windows.Forms.Form

{

TextBox displayTextBox;

UdpClient client;

IPEndPoint receivePoint;

Container components = null;

public Server() // Конструктор по умолчанию

{

InitializeComponent();

client = new UdpClient(5000);

receivePoint = new IPEndPoint(new IPAddress(0), 0);

Thread readThread = new Thread( new ThreadStart(WaitForPackets));

readThread.Start();

}

// Код сгенерированный Visual Studio .NET

[STAThread]

static void Main(){ Application.Run( new Server)); }

// Закрытие сервера

protected void Server_Closing(object sender, CancelEventArgs e)

{ Environment.Exit(Environment.ExitCode)); }

// Ожидание поступления пакета

public void WaitForPackets()

{

while(true)

{

// Получение массива байтов от клиента

byte[] data = client.Receive(ref receivePoint);

// Вывод потоковых данных в TextBox

displayTextBox.Text += "\r\nПакет принят:" +

System.Text.Encoding.ASCII.GetString(data);

displayTextBox.Text +="\r\n\r\nВозвращение данных обратно клиенту";

// Возвращение информации обратно клиенту

client.Send(data,data.Length, receivePoint);

displayTextBox.Text +="\r\nПакет отослан обратно клиенту"

}

}

}

Представленный код определяет класс приложения сервера. В его конструкторе создается экземпляр класса UdpClient, принимающий данные с порта 5000. При этом инициализируется базовый сокет для соединения и создается экземпляр класса IPEndPoint для сохранения IP-адреса и номера порта клиента, осуществляющего передачу данных на сервер. Первый аргумент конструктора класса IPEndPoint – это объект IPAddress, а второй – для номера порта конечной точки соединения. Оба эти значения равны 0, потому что необходимо создать пустой объект IPEndPoint. IP-адреса и номера портов клиентов копируются в объект класса IPEndPoint при получении дэйтаграммы от клиентов.

Метод WaitForPackets() класса сервера выполняет бесконечный цикл, ожидая поступления данных на сервер. При их поступлении метод Receive() класса UdpClient получает от клиента информацию в виде массива байтов. В качестве аргумента в этот метод включен объект receivePoint типа IPEndPoint, созданный в конструкторе. Это обеспечивает данный метод ссылкой на объект, в котором программа копирует IP-адрес и номер клиента. После чего обновляется содержимое текстового поля на форме клиента, а полученные данные с помощью метода UdpClient.Send() отсылаются обратно клиенту. Данная версия этого метода принимает три аргумента: массив байтов для отправки, его размер и объект receivePoint типа IPEndPoint, представляющий собой место назначения данных. Программа скомпилируется и будет выполняться, даже если ссылка на объект receivePoint будет иметь значение null.