Реализация клиента

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

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

// получаемую от сервера

using System;

using System.Drawing;

using System.Collection;

using System.ComponentModel;

using System.Windows.Forms;

using System.Threading;

using System.Net.Sockets;

using System.IO;

// Соединение с сервером

public class Client: System.Windows.Forms.Form

{

TextBox inputTextBox, displayTextBox;

NetworkStream output;

BinaryWriter writer;

BinaryReader reader;

string message = "";

Thread readThread;

Container Components = null;

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

{

InitializeComponent();

readThread = new ThreadStart(RunClient));

readThread.Start();

}

[STAThread]

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

protected void Client_Closing(object sender, CancelEventArg e)

{ Environment.Exit(Environment.ExitCode); }

// отправляет введенный пользователем тест на сервер

protected void inputTextBox_KeyDown(object sender, KeyEventArg e)

{

if(e.keyCode == Keys.Enter)

{

Writer.Write("CLIENT>>> " + inputTextBox.Text);

displayTextBox.Text += "\r\nCLIENT>>> " + inputTextBox.Text;

inputTextBox.Clear();

}

}

// Соединение с сервером и отображение текста, сгенерированного сервером

public void RunClient()

{

TcpClient client;

displayTextBox.Text += "Попытка установить соединение\r\n";

// Создание сокета для отправки данных на сервер

// Шаг 1: Создание сокета и соединение с сервером

client = new TcpClient();

client.Connect("localhost", 5000);

// Шаг 2: Получение потока для работы с сокетом

Output = client.GetStream();

// Создание объектов для записи и считывания в потоке

writer = new BinaryWriter(output);

reader = new BinaryReader(output);

displayTextBox.Text += "\r\nПолучил потоки для ввода и вывода\r\n";

inputTextBox.readOnly = false;

do

{

// Шаг 3: Фаза обработки

message = reader.readString();

displayTextBox.Text += "\r\n" + message;

}

while(message!= "SERVER>>> TERMINATE");

displayTextBox.Text += "\r\nОтключение соединения.\r\n";

// Шаг 4: Закрытие соединения

writer.Close();

reader.Close();

output.Close();

client.Close();

Application.Exit();

}

}

Подобно объекту сервера, объект клиента создает в своем конструкторе поток для обработки всех входящих сообщений. Его метод RunClient () соединяется с объектом сервера, получает от него данные и отправляет и отправляет на сервер свою информацию (при нажатии пользователем на клавишу < ENTER >. На шаге 1, для установления соединения, создается объект типа TcpClient, а затем вызывается его метод Connect (). В данном случае первым аргументом этого метода является имя сервера " localhost ", означающее, что серверное приложение, размещено на той же самой машине, что и клиент. Имя localhost еще называют IP -адресом обратной связи и эквивалентно IP -адресу 127.0.0.1. Это значение направляет передачу данных на IP -адрес отправителя.

Вторым аргументом метода Connect () является номер порта сервера. Этот номер должен совпадать с номером порта, на котором сервер ожидает соединения от клиента.

Объект Client использует класс NetworkStream для передачи данных на сервер и для их получения с сервера. Клиент получает класс NetworkStream путем обращения к методу GetStream класса TcpClient (шаг 2). Цикл do/while повторяется до тех пор, пока не получит сообщения о прекращении соединения (" SERVER>>> TERMINATE "). Для получения с сервера текстового сообщения используется метод ReadString класса BinaryReader (шаг 3). После чего отображаются сообщения и закрываются объекты BinaryWriter, BinaryReader, NetworkStream и TcpClient (шаг 4).

Когда пользователь клиентского приложения вводит строку в текстовое поле и нажимает на клавишу < Enter >, то обработчик этого события inputTextBox_KeyDown считывает строку из текстового поля и отправляет ее серверу с помощью метода BinaryWriter.Write (). Следует отметить, что в данном случае объект сервера получает запрос на соединение, обрабатывает его, закрывает и ожидает следующего. В реальном приложении сервер получил бы запрос на соединение, установил его для обработки в виде отдельного потока и ожидал бы новых соединений. Отдельные потоки, обрабатывающие существующие соединения, могут продолжать свою работу, в то время как объект сервера ожидает новых запросов на соединение.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: