Принципи мережевої взаємодії
Семирівнева модель OSI
Модель OSI (ЕМВВС) (базова еталонна модель взаємодії відкритих систем, англ. Open Systems Interconnection Basic Reference Model, 1978 р.) — абстрактна мережева модель для комунікацій і розробки мережевих протоколів. Представляє рівневий підхід до мережі. Кожен рівень обслуговує свою частину процесу взаємодії. Завдяки такій структурі спільна робота мережевого обладнання й програмного забезпечення стає набагато простішою, прозорішою й зрозумілішою.
В 1978 році Міжнародний комітет зі стандартизації (ISO) розробив стандарт архітектури ISO 7498 для об'єднання різних мереж. У розробці брало участь 7 комітетів, кожному з них був відведений свій рівень. В 1980 році IEEE опублікував специфікацію 802, що детально описала механізми взаємодії фізичних пристроїв на канальному й фізичному рівнях моделі OSI. В 1984 році специфікацію моделі OSI переглянули й прийняли як міжнародний стандарт для мережних комунікацій.
Модель складається з 7-ми рівнів, розташованих вертикально один над іншим. Кожен рівень може взаємодіяти тільки зі своїми сусідами й виконувати відведені тільки йому функції.Забезпечує взаємодію мережі й користувача. Рівень дозволяє додаткам користувача доступ до мережних служб, таких як обробник запитів до баз даних, доступ до файлів, пересилання електронних повідомлень. Також відповідає за передачу службової інформації, надає додаткам інформацію про помилки і формує запити до рівня уявлення. Ідентифікує користувачів по їх паролям, адресам, електронним підписам. Визначає достатність наявних ресурсів. Визначає якість обслуговування. Одиниця даних, якою оперує прикладний рівень, називається повідомленням (message).
Рівень представлення (Presentation layer)
Відповідає за перетворення протоколів і кодування/декодування даних. Запити програм, наданих прикладним рівнем, він перетворює в формат для передачі по мережі, а отримані з мережі дані перетворить у формат, зрозумілий додаткам. На рівні уявлення може здійснюватися стиснення/розпакування або кодування/декодування даних, а також перенаправлення запитів іншому мережному ресурсу, якщо вони не можуть бути оброблені локально.
Відповідає за підтримання сеансу зв'язку, що дозволяє додаткам взаємодіяти між собою тривалий час. Сеансовий рівень управляє створенням/завершенням сеансу, нормальним і терміновим обміном інформацією, взаємодією прикладних процесів, синхронізацією завдань, оповіщеннями при виняткових ситуаціях, визначенням права на передачу даних і підтримкою сеансу в періоди неактивності додатків. Синхронізація передачі забезпечується приміщенням в потік даних контрольних точок(міток), починаючи з яких поновлюється процес при порушенні взаємодії.
Призначений для доставки даних без помилок, втрат і дублювання в тій послідовності, як вони були передані. При цьому неважливо, які дані передаються, звідки і куди, тобто він надає сам механізм передачі. Блоки даних він розділяє на фрагменти, розмір яких залежить від протоколу, короткі об'єднує в один, а довгі розбиває. Протоколи цього рівня призначені для взаємодії типу точка-точка.
Мережевий рівень (Network layer)
Призначений для створення мережевих з'єднань, управління потоками пакетів, організації послідовності пакетів, сегментування та об'єднання пакетів. Відповідає за виявлення та виправлення помилок, що виникають при передачі через комунікаційну мережу, трансляцію логічних адрес і імен у фізичні, визначення найкоротших маршрутів, комутацію і маршрутизацію, відстеження неполадок і заторів в мережі. На цьому рівні працює такий мережний пристрій, як маршрутизатор.
Призначений для організації (встановлення, управління, розірвання) канальних з'єднань і ідентифікації їх портів, забезпечення взаємодії мереж на фізичному рівні і контролю за помилками, які можуть виникнути. Дані, отримані з фізичного рівня, він упаковує у фрейми, перевіряє на цілісність, якщо потрібно виправляє помилки, і відправляє на мережевий рівень. Канальний рівень може взаємодіяти з одним або декількома фізичними рівнями, контролюючи і керуючи цим взаємодією. Специфікація IEEE 802 розділяє цей рівень на 2 підрівні - MAC (Media Access Control) регулює доступ до поділюваного фізичного середовища, LLC (Logical Link Control) забезпечує обслуговування мережного рівня. На цьому рівні працюють комутатори, мости. У програмуванні цей рівень представляє драйвер мережевої плати, в операційних системах є програмний інтерфейс взаємодії канального і мережевого рівнів між собою, це не новий рівень, а просто реалізація моделі для конкретної ОС.
Фізичний рівень (Physical layer)
Призначений безпосередньо для передачі потоку даних. Здійснює передачу електричних або оптичних сигналів в кабель або в радіоефір і відповідно їх прийом і перетворення в біти даних відповідно до методами кодування цифрових сигналів. Іншими словами, здійснює інтерфейс між мережним носієм і мережним пристроєм. На цьому рівні працюють концентратори (хаби), повторювачі (ретранслятори) сигналу і автоматизації виробництва. Функції фізичного рівня реалізуються на всіх пристроях, підключених до мережі. З боку комп'ютера функції фізичного рівня виконуються мережевим адаптером або послідовним портом.
Три нижніх рівні - фізичний, канальний і мережевий - є мережозалежними, тобто протоколи цих рівнів тісно пов'язані з технічною реалізацією мережі, з комунікаційним обладнанням. Наприклад, перехід на обладнання FDDI означає повну зміну протоколів фізичного і канального рівня у всіх вузлах мережі.
Три верхніх рівня - сеансовий, рівень представлення і прикладний - орієнтовані на додатки і мало залежать від технічних особливостей побудови мережі. На протоколи цих рівнів не впливають ніякі зміни в топології мережі, заміна обладнання або перехід на іншу мережеву технологію. Так, перехід від Ethernet на високошвидкісну технологію АТМ не зажадає ніяких змін в програмних засобах, що реалізовують функції прикладного, представницького і сеансового рівнів.
Транспортний рівень є проміжним, він приховує всі деталі функціонування нижніх рівнів від верхніх рівнів. Це дозволяє розробляти додатки, що не залежать від технічних засобів, які безпосередньо займаються транспортуванням повідомлень.
Транспортний рівень є проміжним, він приховує всі деталі функціонування нижніх рівнів від верхніх рівнів. Це дозволяє розробляти додатки, що не залежать від технічних засобів, які безпосередньо займаються транспортуванням повідомлень.
Основна недоробка OSI — непродуманий транспортний рівень. На ньому OSI дозволяє обмін даними між застосунками (вводячи поняття порту — ідентифікатора додатка), однак можливість обміну простими датаграмами в OSI не передбачена — транспортний рівень повинен утворювати з'єднання, забезпечувати доставку, управляти потоком тощо. Реальні ж протоколи реалізують таку можливість.
Стек був розроблений з ініціативи Міністерства оборони США (Department of Defence, DoD) більше 20 років тому для зв'язку експериментальної мережі ARPAnet з іншими сателітними мережами як набір загальних протоколів для різнорідної обчислювальної середовища. Мережа ARPA підтримувала розробників і дослідників у військових областях. У мережі ARPA зв'язок між двома комп'ютерами здійснювалася з використанням протоколу Internet Protocol (IP), який і до цього дня є одним з основних в стеці TCP / IP і фігурує в назві стека.
Великий внесок у розвиток стека TCP / IP вніс університет Берклі, реалізувавши протоколи стека у своїй версії ОС UNIX. Широке поширення ОС UNIX привело і до широкого поширення протоколу IP і інших протоколів стека. На цьому ж стеку працює всесвітня інформаційна мережа Internet, чий підрозділ Internet Engineering Task Force (IETF) вносить основний вклад в удосконалення стандартів стека, що публікуються в формі специфікацій RFC.
Так як стек TCP / IP був розроблений до появи моделі взаємодії відкритих систем ISO / OSI, то, хоча він також має багаторівневу структуру, відповідність рівнів стека TCP / IP рівням моделі OSI досить умовно.
Наступний рівень - це рівень міжмережевої взаємодії, який займається передачею дейтаграм з використанням різних локальних мереж, територіальних мереж X.25, ліній спеціального зв'язку і т. П. В якості основного протоколу мережевого рівня (в термінах моделі OSI) в стеку використовується протокол IP, який спочатку проектувався як протокол передачі пакетів в складових мережах, що складаються з великої кількості локальних мереж, об'єднаних як локальними, так і глобальними зв'язками. Тому протокол IP добре працює в мережах зі складною топологією, раціонально використовуючи наявність у них підсистем і ощадливо витрачаючи пропускну здатність низькошвидкісних ліній зв'язку. Протокол IP є дейтаграмним протоколом.
Наступний рівень називається основним. На цьому рівні функціонують протокол управління передачею TCP (Transmission Control Protocol) і протокол дейтаграм користувача UDP (User Datagram Protocol). Протокол TCP забезпечує стійке віртуальне з'єднання між віддаленими прикладними процесами. Протокол UDP забезпечує передачу прикладних пакетів дейтаграмним методом, тобто без встановлення віртуального з'єднання, і тому вимагає менших накладних витрат, ніж TCP.
Верхній рівень називається прикладним. За довгі роки використання в мережах різних країн і організацій стек TCP / IP нагромадив велику кількість протоколів і сервісів прикладного рівня. До них відносяться такі широко використовувані протоколи, як протокол копіювання файлів FTP, протокол емуляції терміналу telnet, поштовий протокол SMTP, використовуваний в електронній пошті мережі Internet і її російської гілки РЕЛКОМ, гіпертекстові сервіси доступу до вилученої інформації, такі як WWW і багато інших.
Application Programming Interface (API)
API (програмний інтерфейс програми, інтерфейс прикладного програмування) - набір готових класів, процедур, функцій, структур і констант, що надаються додатком (бібліотекою, сервісом) або операційною системою для використання в зовнішніх програмних продуктах. Використовується програмістами при написанні всіляких додатків.
API є абстрактним поняттям — програмне забезпечення, що пропонує деякий API, часто називають реалізацією (англ. implementation) даного API. У багатьох випадках API є частиною набору розробки програмного забезпечення, водночас, набір розробки може включати як API, так і інші інструменти/апаратне забезпечення, отже ці два терміни не є взаємозамінювані.
API визначає функціональність, яку надає програма (модуль, бібліотека), при цьому API дозволяє абстрагуватися від того, як саме ця функціональність реалізована.
Якщо програму (модуль, бібліотеку) розглядати як чорний ящик, то API - це безліч «ручок», які доступні користувачеві даного ящика і які він може крутити і смикати.
Програмні компоненти взаємодіють один з одним за допомогою API. При цьому зазвичай компоненти утворюють ієрархію - високорівневі компоненти використовують API низькорівневих компонентів, а ті, в свою чергу, використовують API ще більш низькорівневих компонентів.
За таким принципом побудовані протоколи передачі даних через Інтернет. Стандартний стек протоколів (мережева модель OSI) містить 7 рівнів (від фізичного рівня передачі біт до рівня протоколів програм, подібних протоколів HTTP і IMAP). Кожен рівень користується функціональністю попереднього («нижчого») рівня передачі даних і, в свою чергу, надає потрібну функціональність наступного («вищерозміщений») рівню.
Важливо зауважити, що поняття протоколу близьке за змістом до поняття API. І те, і інше є абстракцією функціональності, тільки в першому випадку мова йде про передачу даних, а в другому - про взаємодію додатків.
API бібліотеки функцій і класів включає в себе опис сигнатур і семантики функцій.
Сигнатура функції - частина загального оголошення функції, що дозволяє засобам трансляції ідентифікувати функцію серед інших. У різних мовах програмування існують різні уявлення про сигнатурі функції, що також тісно пов'язане з можливостями перевантаження функцій в цих мовах.Важливо зауважити, що поняття протоколу близьке за змістом до поняття API. І те, і інше є абстракцією функціональності, тільки в першому випадку мова йде про передачу даних, а в другому - про взаємодію додатків.
API бібліотеки функцій і класів включає в себе опис сигнатур і семантики функцій.
Іноді розрізняють сигнатуру виклику і сигнатуру реалізації функції. Сигнатура виклику зазвичай складається з синтаксичної конструкції виклику функції з урахуванням сигнатури області видимості даної функції, імені функції, послідовності фактичних типів аргументів у виклику і типі результату. У сигнатурі реалізації зазвичай беруть участь деякі елементи з синтаксичної конструкції оголошення функції: специфікатор області видимості функції, її ім'я і послідовність формальних типів аргументів.
Семантика функції - це опис того, що дана функція робить. Семантика функції включає в себе опис того, що є результатом обчислення функції, як і від чого цей результат залежить. Зазвичай результат виконання залежить тільки від значень аргументів функції, але в деяких модулях є поняття стану.
Тоді результат функції може залежати від цього стану, і, крім того, результатом може стати зміна стану. Логіка цих залежностей і змін відноситься до семантиці функції. Повним описом семантики функцій є виконуваний код функції або математичне визначення функції.
Тоді результат функції може залежати від цього стану, і, крім того, результатом може стати зміна стану. Логіка цих залежностей і змін відноситься до семантиці функції. Повним описом семантики функцій є виконуваний код функції або математичне визначення функції.
Сокети
Сокети (англ. socket - заглиблення, гніздо, роз'єм) — назва програмного інтерфейсу для забезпечення обміну даними між процесами. Процеси при такому обміні можуть виконуватися як на одній ЕОМ, так і на різних ЕОМ, пов'язаних між собою мережею. Сокет - абстрактний об'єкт, що представляє кінцеву точку з'єднання.Слід розрізняти клієнтські і серверні сокети. Клієнтські сокети грубо можна порівняти з кінцевими апаратами телефонної мережі, а серверні - з комутаторами. Клієнтський додаток (наприклад, браузер) використовує лише клієнтські сокети, а серверний (наприклад, веб-сервер, якому браузер посилає запити) - як клієнтські, так і серверні сокети.
Інтерфейс сокетів вперше з'явився в BSD Unix. Програмний інтерфейс сокетів описаний в стандарті POSIX.1 І в тій чи іншій мірі підтримується усіма сучасними операційними системами.
Кожен процес може створити слухаючий сокет (серверний сокет) і прив'язати його до якогось порту операційної системи (в UNIX непривілейовані процеси не можуть використовувати порти менше 1024). Процес, що слухає, зазвичай знаходиться в циклі очікування, тобто прокидається при появі нового з'єднання. При цьому зберігається можливість перевірити наявність з'єднань у цей час, встановити тайм-аут для операції тощо.
Кожен сокет має свою адресу. ОС сімейства UNIX можуть підтримувати багато типів адрес, але обов'язковими є INET-адреса і UNIX-адреса. Якщо прив'язати сокет до UNIX-адреси, то буде створено спеціальний файл (файл сокета) за заданим шляхом, через який зможуть повідомлятися будь-які локальні процеси шляхом читання/запису з нього.
Сокети типу INET доступні з мережі і вимагають виділення номера порту.
Зазвичай клієнт явно під'єднується до слухача, після чого будь-яке читання або запис через його файловий дескриптор будуть передавати дані між ним і сервером.
Зазвичай клієнт явно під'єднується до слухача, після чого будь-яке читання або запис через його файловий дескриптор будуть передавати дані між ним і сервером.
Взаємодія протоколів
Багаторівневі представлення засобів мережевої взаємодії мають свою специфіку, пов'язану з тим, що в процесі обміну повідомленнями беруть участь щонайменше дві сторони, тобто в даному випадку необхідно організувати узгоджену роботу двох ієрархій апаратних і програмних засобів на різних комп'ютерах. Обидва учасники мережевого обміну повинні прийняти безліч угод.Наприклад, вони повинні узгодити рівні і форму електричних сигналів, спосіб визначення розміру повідомлень, домовитися про методи контролю достовірності і т.п. Іншими словами, угоди повинні бути прийняті на всіх рівнях, починаючи від найнижчого - рівня передачі бітів, і закінчуючи найвищим , які реалізують обслуговування користувачів мережі.
Кожен рівень підтримує інтерфейси двох типів. По-перше, це інтерфейси послуг з вище-і нижчого рівнів «своєї» ієрархії засобів. По-друге, це інтерфейс із засобами взаємодії іншого боку, розташованими на тому ж рівні ієрархії. Цей тип інтерфейсу називають протоколом. Таким чином, протокол завжди є одноранговим інтерфейсом.
Ієрархічно організований набір протоколів, достатній для організації взаємодії вузлів в мережі, називається стеком протоколів.
Протоколи нижніх рівнів часто реалізуються комбінацією програмних і апаратних коштів, а протоколи верхніх рівнів, як правило, програмними засобами. Програмний модуль, що реалізовує деякий протокол, називають протокольної сутністю, або, для стислості, теж протоколом. Зрозуміло, що один і той же протокол може бути реалізований з різним ступенем ефективності. Саме тому при порівнянні протоколів слід враховувати не тільки логіку їх роботи, але і якість програмної реалізації. Більш того, на ефективність взаємодії пристроїв в мережі впливає якість усієї сукупності протоколів, що складають стек, зокрема те, наскільки раціонально розподілені функції між протоколами різних рівнів і наскільки добре визначені інтерфейси між ними.
Протокольні представлення одного рівня двох взаємодіючих сторін обмінюються повідомленнями відповідно до визначеного для них протоколом. Повідомлення складаються з заголовка і поля даних (іноді воно може бути відсутнім). Обмін повідомленнями є своєрідною мовою спілкування, за допомогою якого кожна зі сторін «пояснює» іншій стороні, що необхідно зробити на кожному етапі взаємодії.
Робота кожного протокольного модуля полягає в інтерпретації заголовків надходять до нього повідомлень і виконанні пов'язаних з цим дій. Заголовки повідомлень різних протоколів мають різну структуру, що відповідає відмінностям в їх функціональності. зрозуміло, що чим складніше структура заголовка повідомлення, тим складніші функції покладені на відповідний протокол.
Практична реалізація
Наступна програма створює сервер, який отримує запити на з'єднання від клієнтів. Сервер побудований синхронно, отже, виконання потоку блокується, поки сервер не дасть згоди на з'єднання з клієнтом. Ця програма демонструє простий сервер, який відповідає клієнту. Клієнт завершує з'єднання, відправляючи серверу повідомлення <TheEnd>.Сервер TCP
Створення структури сервера показано на наступній функціональної діаграмі:
using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
namespace SocketServer
{
class Program
{
static void Main (string [] args)
{
// Встановлюємо для сокета локальну кінцеву точку
IPHostEntry ipHost = Dns.GetHostEntry ("localhost");
IPAddress ipAddr = ipHost.AddressList [0];
IPEndPoint ipEndPoint = new IPEndPoint (ipAddr, 11000);
// Створюємо сокет Tcp / Ip
Socket sListener = new Socket (ipAddr.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
// Призначаємо сокет локальної кінцевій точці і слухаємо вхідні сокети
try
{
sListener.Bind (ipEndPoint);
sListener.Listen (10);
// Починаємо слухати з'єднання
while (true)
{
Console.WriteLine ( "Очікуємо з'єднання через порт {0}", ipEndPoint);
// Програма призупиняється, чекаючи вхідні повідомлення
Socket handler = sListener.Accept ();
string data = null;
// Ми дочекалися клієнта, який намагається з нами з'єднатися
byte [] bytes = new byte [1024];
int bytesRec = handler.Receive (bytes);
data + = Encoding.UTF8.GetString (bytes, 0, bytesRec);
// Показуємо дані на консолі
Console.Write ( "Отриманий текст:" + data + "\ n \ n");
// Відправляємо відповідь клієнту \
string reply = "Спасибі за запит в" + data.Length.ToString ()
+ "символів";
byte [] msg = Encoding.UTF8.GetBytes (reply);
handler.Send (msg);
if (data.IndexOf ( "<TheEnd>")> -1)
{
Console.WriteLine ( "Сервер завершив з'єднання з клієнтом.");
break;
}
handler.Shutdown (SocketShutdown.Both);
handler.Close ();
}
}
catch (Exception ex)
{
Console.WriteLine (ex.ToString ());
}
finally
{
Console.ReadLine ();
}
}
}
}
Перший крок полягає у встановленні для сокета локальної кінцевої точки. Перш ніж відкривати сокет для очікування з'єднань, потрібно підготувати для нього адресу локальної кінцевої точки. Унікальна адреса для обслуговування TCP / IP визначається комбінацією IP-адреси хоста з номером порту обслуговування, яка створює кінцеву точку для обслуговування.
Клас Dns надає методи, які повертають інформацію про мережеві адреси, підтримуваних пристроєм в локальній мережі. Якщо у пристроя локальної мережі є більше одного мережевого адреса, клас Dns повертає інформацію про всі мережеві адреси, і додаток повинен вибрати з масиву відповідну адресу для обслуговування.
Створимо IPEndPoint для сервера, комбінуючи перший IP-адреса хост-комп'ютера, отриманий від методу Dns.Resolve (), з номером порту:
IPAddress ipAddr = ipHost.AddressList[0];
IPEndPoint ipEndPoint = new IPEndPoint(ipAddr, 11000);
Тут клас 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 ().
Тепер, створивши сокет і зв'язавши з ним ім'я, можна слухати вхідні повідомлення, скориставшись методом Listen (). У стані прослуховування сокет чекатиме входять спроби з'єднання:
У параметрі визначається заділ (backlog), який вказує максимальне число з'єднань, які очікують обробки в черзі. У наведеному коді значення параметра допускає накопичення в черзі до десяти з'єднань.
У стані прослуховування треба бути готовим дати згоду на з'єднання з клієнтом, для чого використовується метод Accept (). За допомогою цього методу виходить з'єднання клієнта і завершується встановлення зв'язку імен клієнта і сервера. Метод Accept () блокує потік викличеної програми до надходження з'єднання.
Метод Accept () витягує з черги очікуваючих запитів перший запит на з'єднання і створює для його обробки новий сокет. Хоча новий сокет створений, початковий сокет продовжує слухати і може використовуватися з багатопотокової обробкою для прийому декількох запитів на з'єднання від клієнтів. Ніякий серверний додаток не повинен закривати слухаючий сокет. Він повинен продовжувати працювати поряд з сокетами, створеними методом Accept() для обробки вхідних запитів клієнтів.
Socket handler = sListener.Accept();
Як тільки клієнт і сервер встановили між собою з'єднання, можна відправляти і отримувати повідомлення, використовуючи методи Send () і Receive () класу Socket.
Метод Send () записує вихідні дані сокету, з яким встановлено з'єднання. Метод Receive () зчитує вхідні дані в потоковий сокет. При використанні системи, заснованої на TCP, перед виконанням методів Send () і Receive () між сокетами має бути встановлено з'єднання. Точний протокол між двома взаємодіючими сутностями повинен бути визначений завчасно, щоб клієнтський і серверний додатки не блокували один одного, не знаючи, хто повинен відправити свої дані першим.
Коли обмін даними між сервером і клієнтом завершується, потрібно закрити з'єднання використовуючи методи Shutdown () і Close ():
handler.Close();
SocketShutdown - це перерахування, що містить три значення для зупинки: Both - зупиняє відправку та отримання даних сокетом, Receive - зупиняє отримання даних сокетом і Send - зупиняє відправку даних сокетом.
Сокет закривається при виклику методу Close (), який також встановлює у властивості Connected сокета значення false.
Клієнт на TCP
Функції, які використовуються для створення програми-клієнта, більш-менш нагадують серверний додаток. Як і для сервера, використовуються ті ж методи для визначення кінцевої точки, створення екземпляра сокета, відправки та отримання даних та закриття сокета:
using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
namespace SocketClient
{
class Program
{
static void Main (string [] args)
{
try
{
SendMessageFromSocket (11000);
}
catch (Exception ex)
{
Console.WriteLine (ex.ToString ());
}
finally
{
Console.ReadLine ();
}
}
static void SendMessageFromSocket (int port)
{
// Буфер для вхідних даних
byte [] bytes = new byte [1024];
// З'єднуємося з віддаленим пристроєм
// Встановлюємо віддалену точку для сокета
IPHostEntry ipHost = Dns.GetHostEntry ( "localhost");
IPAddress ipAddr = ipHost.AddressList [0];
IPEndPoint ipEndPoint = new IPEndPoint (ipAddr, port);
Socket sender = new Socket (ipAddr.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
// З'єднуємо сокет з віддаленою точкою
sender.Connect (ipEndPoint);
Console.Write ( "Введіть повідомлення:");
string message = Console.ReadLine ();
Console.WriteLine ( "Сокет з'єднується з {0}", sender.RemoteEndPoint.ToString ());
byte [] msg = Encoding.UTF8.GetBytes (message);
// Відправляємо дані через сокет
int bytesSent = sender.Send (msg);
// Отримуємо відповідь від сервера
int bytesRec = sender.Receive (bytes);
Console.WriteLine ( "\ nОтвет від сервера: {0} \ n \ n", Encoding.UTF8.GetString (bytes, 0, bytesRec));
// Використовуємо рекурсию для неодноразового виклику SendMessageFromSocket ()
if (message.IndexOf ( "<TheEnd>") == -1)
SendMessageFromSocket (port);
// Звільняємо сокет
sender.Shutdown (SocketShutdown.Both);
sender.Close ();
}
}
}
На рисунку нижче показані клієнт і сервер в дії:
Коментарі
Дописати коментар