Создание клиент серверного приложения в visual studio

Обновлено: 06.07.2024

WCF - Windows Communication Foundation, программный фреймворк, используемый для обмена данными между приложениями.

Почему стоит использовать это решение, а не сделать свой клиент-сервер ?

1. Данное решение многопоточное. Это значит, что одновременно могут серверу поступить запросы от многих клиентов и клиенты не будут ждать друг друга в очереди, а каждый запрос будет выполнен в отдельном параллельном потоке.

2. Решение не имеет большого объема кода, а значит понять данный код легче.

3. Вам не придется вдаваться в подробности работы между клиентом и сервером: тот самый случай когда установил и забыл о проблемах.

Интерфейс определяет как будет выглядеть объект, в котором будут методы работы нашего клиент-сервера. В WCF данный интерфейс называется контрактом.

Замечание: если Вы создаете клиент-сервер не для теста в рамках одного приложения, а клиент и сервер будут разными приложениями, то Вам следует создать интерфейс ITransferObject и класс TransferObject в отдельной библиотеке dll. В таком случае Ваше клиентское и серверное приложения будут использовать одни классы и интерфейсы, что является Важным условием для WCF.
В данном примере определим, что данный объект будет иметь 2 простых метода:
GetSum - подсчет суммы двух целых чисел
GetMultiPly - подсчет умножения двух целых чисел

[ServiceContract] - необходимый модификатор чтобы указать что данный интерфейс является контрактом WCF службы.
[OperationContract] - необходимый модификатор чтобы указать что данные методы будут использоваться в контракте.

Класс TransferObject унаследуем от интерфейса ITransferObject. Данный класс будет иметь простую реализацию наших методов.
При вызове метода GetSum будут переданы 2 целых числа.Ответом выполним сложение этих чисел.

Соответственно и с методом GetMultiPly - ответом выполним перемножение этих чисел.

public class TransferObject : ITransferObject < public int GetSum(int a, int b) < return a + b; >public int GetMultiPly(int a, int b) < return a * b; >> static void Main(string[] args) < var serviceAddress = "127.0.0.1:10000"; var serviceName = "MyService"; var host = new ServiceHost(typeof(TransferObject), new Uri($"net.tcp:///")); var serverBinding = new NetTcpBinding(); host.AddServiceEndpoint(typeof(ITransferObject), serverBinding, ""); host.Open(); Console.ReadKey(); >

serviceAddress - это адрес на котором сервер будет ожидать подключения от клиентов.
serviceName - имя сервиса. На каждом адресе может быть большое количество сервисов. Имя сервиса - часть адреса, по которому клиент подключается к серверу.
Далее происходит запуск серверной части WCF. Чтобы приложение не закрылось после отработки всего кода, добавлено Console.ReadKey() - ожидание нажатия любой клавиши.

static void Main(string[] args) < var serviceAddress = "127.0.0.1:10000"; var serviceName = "MyService"; Uri tcpUri = new Uri($"net.tcp:///"); EndpointAddress address = new EndpointAddress(tcpUri); NetTcpBinding clientBinding = new NetTcpBinding(); ChannelFactory<ITransferObject> factory = new ChannelFactory<ITransferObject>(clientBinding, address); var service = factory.CreateChannel(); var sum = service.GetSum(4, 7); var multiply = service.GetMultiPly(3, 17); Console.WriteLine($"sum = "); Console.WriteLine($"multiply = "); Console.ReadKey(); >

Строка подключения к серверу такая же как используется в серверной части: адрес_сервера + имя сервиса.

Далее происходит инициализация клиенской части WCF и вызов методов сложения и умножения чисел.

Дано три стороны треугольника: a , b , c .

Используя формулу Герона, разработать приложение, которое находит площадь треугольника. Приложение реализовать как Web-application .

Формула Герона имеет вид:

Формула Герона

где p – полупериметр:

a, b, c – длина сторон треугольника.

Выполнение

1. Запустить MS Visual Studio

Пример создания приложения в MS Visual Studio по шаблону Windows Forms Application подробно описывается в теме:

2. Создание Web-приложения

Приложения типа Web могут вызываться из любого компьютера, подключенного к сети Internet. Для открытия такого приложения используется Web -браузер (например Opera , Google Chrome , Internet Explorer и другие).

Ниже указаны два способа создания Web -приложения в MS Visual Studio .

2.1. Создание Web-приложения (способ № 1)

Для этого способа, чтобы создать Web -приложение, нужно сначала вызвать команду (рис. 1):

Рис. 1. Команда создания нового веб-сайта

Например, в нашем случае, файлы будут сохраняться в папке

MS Visual Studio команда создания Web-сайта

Рис. 2. Создание Web-сайта

2.2. Создание Web-приложения (способ № 2)

Существует также и другой способ создания Web -приложения с помощью команды (рис. 3)

Visual Studio Команда ASP .NET Empty Web Site

Рис. 3. Команда создания нового проекта

Рис. 4. Команда создания Web-приложения

3. Создание приложения как веб-сайта

Для решения задачи выбираем первый способ.

После выполненных операций создается решение ( Solution ), в котором есть один проект типа веб-сайт (рис. 5).

Окно "Solution Explorer" создание веб-сайта

Если запустить на выполнение данный проект, то внизу в правой части экрана ( SySTray ) отобразится окно загруженного локального сервера (рис. 6).

Visual Studio локальный сервер выполнение приложения

Рис. 6. Загрузка локального сервера для выполнения приложения

В результате запуска, в активном веб-браузере откроется страница с приблизительно таким текстом (рис. 8):

Рис. 8. Текст, который выводится в веб-браузере

4. Добавление формы к приложению

Добавим новую форму к Web -приложению.

Рис. 10. Добавление новой формы

После добавления, в Solution Explorer можно увидеть дополнительные два файла (рис. 11):

С помощью этих двух файлов можно изменять внешний вид формы и организовывать работу в ней.

Visual Studio Файлы формы "Default.aspx" "Default.aspx.cs"

С помощью кнопок Design и Source можно переключаться между режимом проектирования и режимом кода страницы Default.aspx (рис. 12).

Рис. 12. Режимы проектирования ( Design ) и кода ( Source )

5. Конструирование формы

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

5.1. Изменение размеров формы

Рис. 13. Изменение размеров формы в режиме проектирования

Для нашей задачи нужно вынести на форму следующие элементы управления:

При вынесении элемента управления в правой нижней части экрана (окно Properties ) можно изменять свойства элементов управления (рис. 14).

Рис. 14. Изменение свойств элементов управления Web -формы

В целом, после построения, форма приложения должна иметь вид как показано на рисунке 15.

Рис. 15. Форма приложения в режиме проектирования

using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; public partial class _Default : System.Web.UI.Page < protected void Page_Load( object sender, EventArgs e) < >protected void Button1_Click( object sender, EventArgs e) < double a, b, c, p, s; a = Double .Parse(TextBox1.Text); b = Double .Parse(TextBox2.Text); c = Double .Parse(TextBox3.Text); p = (a + b + c) / 2; s = Math .Sqrt(p * (p - a) * (p - b) * (p - c)); Label4.Text = "S text-align: justify;">После запуска приложения на выполнение можно проконтролировать его работу в Web -браузере (рис. 16).

Рис. 16. Выполнение Web -приложения в браузере Opera

После этого можно выносить приложение на Web-сервер. Но это уже другая тема.

В следующем примере используем TCP, чтобы обеспечить упорядоченные, надежные двусторонние потоки байтов. Построим завершенное приложение, включающее клиент и сервер. Сначала демонстрируем, как сконструировать на потоковых сокетах TCP сервер, а затем клиентское приложение для тестирования нашего сервера.

Сервер TCP

Создание структуры сервера показано на следующей функциональной диаграмме:

Схема .NET-сервера

Вот полный код программы SocketServer.cs:

Давайте рассмотрим структуру данной программы.

Первый шаг заключается в установлении для сокета локальной конечной точки. Прежде чем открывать сокет для ожидания соединений, нужно подготовить для него адрес локальной конечной точки. Уникальный адрес для обслуживания TCP/IP определяется комбинацией IP-адреса хоста с номером порта обслуживания, которая создает конечную точку для обслуживания.

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

Создадим IPEndPoint для сервера, комбинируя первый IP-адрес хост-компьютера, полученный от метода Dns.Resolve(), с номером порта:

Здесь класс IPEndPoint представляет localhost на порте 11000. Далее новым экземпляром класса Socket создаем потоковый сокет. Установив локальную конечную точку для ожидания соединений, можно создать сокет:

Перечисление AddressFamily указывает схемы адресации, которые экземпляр класса Socket может использовать для разрешения адреса.

В параметре SocketType различаются сокеты TCP и UDP. В нем можно определить в том числе следующие значения:

Dgram

Поддерживает дейтаграммы. Значение Dgram требует указать Udp для типа протокола и InterNetwork в параметре семейства адресов.

Raw

Поддерживает доступ к базовому транспортному протоколу.

Stream

Поддерживает потоковые сокеты. Значение Stream требует указать Tcp для типа протокола.

Третий и последний параметр определяет тип протокола, требуемый для сокета. В параметре РrotocolType можно указать следующие наиболее важные значения - Tcp, Udp, Ip, Raw.

Следующим шагом должно быть назначение сокета с помощью метода Bind(). Когда сокет открывается конструктором, ему не назначается имя, а только резервируется дескриптор. Для назначения имени сокету сервера вызывается метод Bind(). Чтобы сокет клиента мог идентифицировать потоковый сокет TCP, серверная программа должна дать имя своему сокету:

Метод Bind() связывает сокет с локальной конечной точкой. Вызывать метод Bind() надо до любых попыток обращения к методам Listen() и Accept().

В параметре определяется задел (backlog), указывающий максимальное число соединений, ожидающих обработки в очереди. В приведенном коде значение параметра допускает накопление в очереди до десяти соединений.

В состоянии прослушивания надо быть готовым дать согласие на соединение с клиентом, для чего используется метод Accept(). С помощью этого метода получается соединение клиента и завершается установление связи имен клиента и сервера. Метод Accept() блокирует поток вызывающей программы до поступления соединения.

Метод Accept() извлекает из очереди ожидающих запросов первый запрос на соединение и создает для его обработки новый сокет. Хотя новый сокет создан, первоначальный сокет продолжает слушать и может использоваться с многопоточной обработкой для приема нескольких запросов на соединение от клиентов. Никакое серверное приложение не должно закрывать слушающий сокет. Он должен продолжать работать наряду с сокетами, созданными методом Accept для обработки входящих запросов клиентов.

Когда обмен данными между сервером и клиентом завершается, нужно закрыть соединение используя методы Shutdown() и Close():

SocketShutdown — это перечисление, содержащее три значения для остановки: Both - останавливает отправку и получение данных сокетом, Receive - останавливает получение данных сокетом и Send - останавливает отправку данных сокетом.

Сокет закрывается при вызове метода Close(), который также устанавливает в свойстве Connected сокета значение false.

Клиент на TCP

Функции, которые используются для создания приложения-клиента, более или менее напоминают серверное приложение. Как и для сервера, используются те же методы для определения конечной точки, создания экземпляра сокета, отправки и получения данных и закрытия сокета:

Клиентское приложение, использующее сокеты

Вот полный код для SocketClient.cs и его объяснение:

Единственный новый метод - метод Connect(), используется для соединения с удаленным сервером. На рисунке ниже показаны клиент и сервер в действии:

БлогNot. Пишем консольный сервер и клиент на C++ в Windows 32/64

Пишем консольный сервер и клиент на C++ в Windows 32/64

Как обычно, создаём новый пустой проект C++, но для решения указываем имя, например, ClientServer , а для проекта - другое имя, пусть будет Server .

Потом ещё раз создаём пустой проект с именем Client , но добавляем его в то то же самое решение.

Жмём правую кнопку мыши на "исходных файлах" приложения-сервера, выбираем команды Добавить, Создать элемент, Visual C++, файл C++, имя файла с исходным текстом можно оставить Source.cpp (по умолчанию).

Вот полный исходник этого файла, откомпилированный в Visual Studio 2019 под актуальной сборкой Windows 10.

Я выбрал в стандартной панели инструментов конфигурацию Debug - X64. Если нужно, разрешить приложению работать с сетью, подтверждаем это.

Разрешить консольному приложению сервера доступ к сети


Разрешить консольному приложению сервера доступ к сети

Аналогично добавляем файл Source.cpp в приложение Client , вот его полный исходный код, так как он, в сущности, очень похож, можно без столь подробных комментариев:

Обратите внимание на директивы покдлючения библиотек в начале обоих листингов.

В Обозревателе Решений жмём правую кнопку на заголовке решения (самого верхнего уровня), выбираем "Назначить запускаемые проекты", подтверждаем запуск нескольких проектов.

Запуск нескольких проектов из решения


Запуск нескольких проектов из решения

Проект в работе


Проект в работе

Так как опции решения хранятся в файле .suo вместе с асболютными путями к файлам проекта (а у вас эти пути точно не совпадут с моими), то действие со второго рисунка ("Запуск нескольких проектов из решения") в скачанном проекте будет не настроено.

Читайте также: