Как да създадете мрежово приложение в Java (със снимки)

Съдържание:

Как да създадете мрежово приложение в Java (със снимки)
Как да създадете мрежово приложение в Java (със снимки)

Видео: Как да създадете мрежово приложение в Java (със снимки)

Видео: Как да създадете мрежово приложение в Java (със снимки)
Видео: Как вывести экран смартфона на телевизор | ВСЕ СПОСОБЫ 2024, Може
Anonim

Писането на код, който се изпълнява на определено устройство, е много удовлетворяващо. Но писането на код, който се изпълнява на няколко устройства, които комуникират помежду си, е просто животворящо. Тази статия ще ви научи как да се свързвате и обменяте съобщения по мрежата, използвайки протокол за управление на предаването (TCP).

В тази статия ще настроите приложение, което ще свърже компютъра ви със себе си и по същество ще го направи луд - говорете със себе си. Ще научите и разликата между двата най -широко използвани потока за работа в мрежа в Java и как те функционират.

Потоци от данни и обекти

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

Потоци от данни

Потоците от данни обработват примитивни типове данни и низове. Данните, изпратени по потоци от данни, трябва да бъдат ръчно сериализирани и десериализирани, което затруднява прехвърлянето на сложни данни. Но потоците от данни могат да комуникират със сървъри и клиенти, написани на други езици, различни от Java. Суровите потоци са подобни на потоците от данни в този аспект, но потоците от данни гарантират, че данните са форматирани по независим от платформата начин, което е от полза, тъй като и двете страни ще могат да четат изпратените данни.

Обектни потоци

Обектните потоци обработват примитивни типове данни и обекти, които имплементират

Сериализирано

интерфейс. Данните, изпращани през потоци от обекти, автоматично се сериализират и десериализират, което улеснява прехвърлянето на сложни данни. Но обектните потоци могат да комуникират само със сървъри и клиенти, написани на Java. Също,

ObjectOutputStream

при инициализация, изпраща заглавка към

InputStream

на другата страна, която при инициализация блокира изпълнението, докато се получи заглавката.

Стъпки

Създайте мрежово приложение в Java Step1
Създайте мрежово приложение в Java Step1

Стъпка 1. Създайте клас

Създайте клас и го наименувайте както искате. В тази статия той ще бъде кръстен

NetworkAppExample

публичен клас NetworkAppExample {}

Създайте мрежово приложение в Java Step2
Създайте мрежово приложение в Java Step2

Стъпка 2. Създайте основен метод

Създайте основен метод и декларирайте, че може да хвърли изключения от

Изключение

тип и всеки негов подклас - всички изключения. Това се счита за лоша практика, но е приемливо за примери с гола кост.

публичен клас NetworkAppExample {public static void main (String args) throws Exception {}}

Създайте мрежово приложение в Java Step3
Създайте мрежово приложение в Java Step3

Стъпка 3. Декларирайте адреса на сървъра

Този пример ще използва локален адрес на хост и произволен номер на порт. Номерът на порта трябва да бъде в диапазона от 0 до 65535 (включително). Номерата на портовете, които трябва да се избягват, варират от 0 до 1023 (включително), тъй като те са запазени системни портове.

публичен клас NetworkAppExample {public static void main (String args) изхвърля Exception {String host = "localhost"; int порт = 10430; }}

Създайте мрежово приложение в Java Step4
Създайте мрежово приложение в Java Step4

Стъпка 4. Създайте сървър

Сървърът е свързан с адреса и порта и слуша за входящи връзки. В Java,

ServerSocket

представлява крайната точка на сървъра и нейната функция е приемане на нови връзки.

ServerSocket

няма потоци за четене и изпращане на данни, защото не представлява връзка между сървър и клиент.

внос java.net. InetAddress; импортиране на java.net. ServerSocket; публичен клас NetworkAppExample {public static void main (String args) изхвърля Exception {String host = "localhost"; int порт = 10430; ServerSocket сървър = нов ServerSocket (порт, 50, InetAddress.getByName (хост)); }}

Създайте мрежово приложение в Java Step5
Създайте мрежово приложение в Java Step5

Стъпка 5. Начало на сървъра за регистрация

За целите на регистрирането отпечатайте на конзолата, че сървърът е стартиран.

внос java.net. InetAddress; импортиране на java.net. ServerSocket; публичен клас NetworkAppExample {public static void main (String args) изхвърля Exception {String host = "localhost"; int порт = 10430; ServerSocket сървър = нов ServerSocket (порт, 50, InetAddress.getByName (хост)); System.out.println ("Сървърът е стартиран."); }}

Създайте мрежово приложение в Java Step6
Създайте мрежово приложение в Java Step6

Стъпка 6. Създайте клиент

Клиентът е свързан с адреса и порта на сървър и слуша пакети (съобщения) след установяване на връзка. В Java,

Гнездо

представлява или клиентска крайна точка, свързана към сървъра, или връзка (от сървър) към клиент и се използва за комуникация със страната от другата страна.

внос java.net. InetAddress; импортиране на java.net. ServerSocket; внос java.net. Socket; публичен клас NetworkAppExample {public static void main (String args) изхвърля Exception {String host = "localhost"; int порт = 10430; ServerSocket сървър = нов ServerSocket (порт, 50, InetAddress.getByName (хост)); System.out.println ("Сървърът е стартиран."); Сокет клиент = нов гнездо (хост, порт); }}

Създайте мрежово приложение в Java Step7
Създайте мрежово приложение в Java Step7

Стъпка 7. Опитът за регистриране на връзка

За целите на регистрирането отпечатайте на конзолата, че е направена опит за свързване.

внос java.net. InetAddress; импортиране на java.net. ServerSocket; внос java.net. Socket; публичен клас NetworkAppExample {public static void main (String args) изхвърля Exception {String host = "localhost"; int порт = 10430; ServerSocket сървър = нов ServerSocket (порт, 50, InetAddress.getByName (хост)); System.out.println ("Сървърът е стартиран."); Сокет клиент = нов гнездо (хост, порт); System.out.println ("Свързване със сървър …"); }}

Създайте мрежово приложение в Java Step8
Създайте мрежово приложение в Java Step8

Стъпка 8. Установете връзка

Клиентите никога няма да се свържат, освен ако сървърът не слуша и приема, с други думи, установява връзки. В Java връзките се установяват с помощта

приемам ()

метод на

ServerSocket

клас. Методът ще блокира изпълнението, докато клиентът не се свърже.

внос java.net. InetAddress; импортиране на java.net. ServerSocket; внос java.net. Socket; публичен клас NetworkAppExample {public static void main (String args) изхвърля Exception {String host = "localhost"; int порт = 10430; ServerSocket сървър = нов ServerSocket (порт, 50, InetAddress.getByName (хост)); System.out.println ("Сървърът е стартиран."); Сокет клиент = нов гнездо (хост, порт); System.out.println ("Свързване със сървър …"); Сокет връзка = server.accept (); }}

Създайте мрежово приложение в Java Step9
Създайте мрежово приложение в Java Step9

Стъпка 9. Влезте в установената връзка

За целите на регистрирането отпечатайте на конзолата, че връзката между сървъра и клиента е установена.

внос java.net. InetAddress; импортиране на java.net. ServerSocket; внос java.net. Socket; публичен клас NetworkAppExample {public static void main (String args) изхвърля Exception {String host = "localhost"; int порт = 10430; ServerSocket сървър = нов ServerSocket (порт, 50, InetAddress.getByName (хост)); System.out.println ("Сървърът е стартиран."); Сокет клиент = нов сокет (хост, порт); System.out.println ("Свързване със сървър …"); Сокет връзка = server.accept (); System.out.println ("Връзка установена."); }}

Създайте мрежово приложение в Java Step10
Създайте мрежово приложение в Java Step10

Стъпка 10. Подгответе комуникационни потоци

Комуникацията се осъществява през потоци и в това приложение необработените потоци от (връзка от) сървър (към клиент) и клиент трябва да бъдат свързани към потоци от данни или обекти. Не забравяйте, че и двете страни трябва да използват един и същ тип поток.

  • Потоци от данни

    импортиране на java.io. DataInputStream; импортиране на java.io. DataOutputStream; внос java.net. InetAddress; импортиране на java.net. ServerSocket; внос java.net. Socket; публичен клас NetworkAppExample {public static void main (String args) изхвърля Exception {String host = "localhost"; int порт = 10430; ServerSocket сървър = нов ServerSocket (порт, 50, InetAddress.getByName (хост)); System.out.println ("Сървърът е стартиран."); Сокет клиент = нов сокет (хост, порт); System.out.println ("Свързване със сървър …"); Сокет връзка = server.accept (); System.out.println ("Връзка установена."); DataOutputStream clientOut = нов DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = нов DataInputStream (client.getInputStream ()); DataOutputStream serverOut = нов DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = нов DataInputStream (connection.getInputStream ()); }}

  • Обектни потоци

    Когато се използват множество обектни потоци, входните потоци трябва да бъдат инициализирани в същия ред като изходните потоци, защото

    ObjectOutputStream

    изпраща заглавка на другата страна и

    ObjectInputStream

    блокира изпълнението, докато не прочете заглавието.

    импортиране на java.io. ObjectInputStream; импортиране на java.io. ObjectOutputStream; внос java.net. InetAddress; импортиране на java.net. ServerSocket; внос java.net. Socket; публичен клас NetworkAppExample {public static void main (String args) изхвърля Exception {String host = "localhost"; int порт = 10430; ServerSocket сървър = нов ServerSocket (порт, 50, InetAddress.getByName (хост)); System.out.println ("Сървърът е стартиран."); Сокет клиент = нов сокет (хост, порт); System.out.println ("Свързване със сървър …"); Сокет връзка = server.accept (); System.out.println ("Връзка установена."); ObjectOutputStream clientOut = нов ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = нов ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = нов ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = нов ObjectInputStream (connection.getInputStream ()); }}

    Поръчката, както е посочено в кода по -горе, може да бъде по -лесна за запомняне - първо инициализирайте изходните потоци, след това входните потоци в същия ред. Друг ред за инициализиране на обектни потоци обаче е следният:

    ObjectOutputStream clientOut = нов ObjectOutputStream (client.getOutputStream ()); ObjectInputStream serverIn = нов ObjectInputStream (connection.getInputStream ()); ObjectOutputStream serverOut = нов ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = нов ObjectInputStream (client.getInputStream ());

Създайте мрежово приложение в Java Step11
Създайте мрежово приложение в Java Step11

Стъпка 11. Влезте, че комуникацията е готова

За целите на регистрирането отпечатайте на конзолата, че комуникацията е готова.

// код пропуснат import java.net. InetAddress; импортиране на java.net. ServerSocket; внос java.net. Socket; публичен клас NetworkAppExample {public static void main (String args) изхвърля Exception {String host = "localhost"; int порт = 10430; ServerSocket сървър = нов ServerSocket (порт, 50, InetAddress.getByName (хост)); System.out.println ("Сървърът е стартиран."); Сокет клиент = нов гнездо (хост, порт); System.out.println ("Свързване със сървър …"); Сокет връзка = server.accept (); System.out.println ("Връзка установена."); // кодът е пропуснат System.out.println ("Комуникацията е готова."); }}

Създайте мрежово приложение в Java Step12
Създайте мрежово приложение в Java Step12

Стъпка 12. Създайте съобщение

В това приложение,

Здравей свят

текстът ще бъде изпратен на сървъра или като

байт

или

Низ

. Обявете променлива от типа, която зависи от използвания поток. Използвайте

байт

за потоци от данни и

Низ

за потоци от обекти.

  • Потоци от данни

    Използвайки потоци от данни, сериализацията се извършва чрез преобразуване на обекти в примитивни типове данни или a

    Низ

    . В такъв случай,

    Низ

    се преобразува в

    байт

    вместо да се пише с помощта

    writeBytes ()

    метод, за да покаже как би било направено с други обекти, като изображения или други файлове.

    импортиране на java.io. DataInputStream; импортиране на java.io. DataOutputStream; внос java.net. InetAddress; импортиране на java.net. ServerSocket; внос java.net. Socket; публичен клас NetworkAppExample {public static void main (String args) изхвърля Exception {String host = "localhost"; int порт = 10430; ServerSocket сървър = нов ServerSocket (порт, 50, InetAddress.getByName (хост)); System.out.println ("Сървърът е стартиран."); Сокет клиент = нов сокет (хост, порт); System.out.println ("Свързване със сървър …"); Сокет връзка = server.accept (); System.out.println ("Връзка установена."); DataOutputStream clientOut = нов DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = нов DataInputStream (client.getInputStream ()); DataOutputStream serverOut = нов DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = нов DataInputStream (connection.getInputStream ()); System.out.println ("Комуникацията е готова."); byte messageOut = "Здравей свят".getBytes (); }}

  • Обектни потоци

    импортиране на java.io. ObjectInputStream; импортиране на java.io. ObjectOutputStream; внос java.net. InetAddress; импортиране на java.net. ServerSocket; внос java.net. Socket; публичен клас NetworkAppExample {public static void main (String args) изхвърля Exception {String host = "localhost"; int порт = 10430; ServerSocket сървър = нов ServerSocket (порт, 50, InetAddress.getByName (хост)); System.out.println ("Сървърът е стартиран."); Сокет клиент = нов гнездо (хост, порт); System.out.println ("Свързване със сървър …"); Сокет връзка = server.accept (); System.out.println ("Връзка установена."); ObjectOutputStream clientOut = нов ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = нов ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = нов ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = нов ObjectInputStream (connection.getInputStream ()); System.out.println ("Комуникацията е готова."); String messageOut = "Hello World"; }}

Създайте мрежово приложение в Java Step13
Създайте мрежово приложение в Java Step13

Стъпка 13. Изпратете съобщението

Запишете данни в изходния поток и промийте потока, за да сте сигурни, че данните са изписани изцяло.

  • Потоци от данни

    Първо трябва да се изпрати дължината на съобщението, за да знае другата страна колко байта трябва да прочете. След като дължината е изпратена като примитивен цяло число, могат да бъдат изпратени байтове.

    импортиране на java.io. DataInputStream; импортиране на java.io. DataOutputStream; внос java.net. InetAddress; импортиране на java.net. ServerSocket; внос java.net. Socket; публичен клас NetworkAppExample {public static void main (String args) изхвърля Exception {String host = "localhost"; int порт = 10430; ServerSocket сървър = нов ServerSocket (порт, 50, InetAddress.getByName (хост)); System.out.println ("Сървърът е стартиран."); Сокет клиент = нов сокет (хост, порт); System.out.println ("Свързване със сървър …"); Сокет връзка = server.accept (); System.out.println ("Връзка установена."); DataOutputStream clientOut = нов DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = нов DataInputStream (client.getInputStream ()); DataOutputStream serverOut = нов DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = нов DataInputStream (connection.getInputStream ()); System.out.println ("Комуникацията е готова."); byte messageOut = "Здравей свят".getBytes (); clientOut.writeInt (messageOut.length); clientOut.write (messageOut); clientOut.flush (); }}

  • Обектни потоци

    импортиране на java.io. ObjectInputStream; импортиране на java.io. ObjectOutputStream; внос java.net. InetAddress; импортиране на java.net. ServerSocket; внос java.net. Socket; публичен клас NetworkAppExample {public static void main (String args) изхвърля Exception {String host = "localhost"; int порт = 10430; ServerSocket сървър = нов ServerSocket (порт, 50, InetAddress.getByName (хост)); System.out.println ("Сървърът е стартиран."); Сокет клиент = нов сокет (хост, порт); System.out.println ("Свързване със сървър …"); Сокет връзка = server.accept (); System.out.println ("Връзка установена."); ObjectOutputStream clientOut = нов ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = нов ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = нов ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = нов ObjectInputStream (connection.getInputStream ()); System.out.println ("Комуникацията е готова."); String messageOut = "Здравей свят"; clientOut.writeObject (messageOut); clientOut.flush (); }}

Създайте мрежово приложение в Java Step14
Създайте мрежово приложение в Java Step14

Стъпка 14. Влезте в изпратеното съобщение

За целите на регистрирането отпечатайте съобщението до конзолата, че е изпратено.

  • Потоци от данни

    импортиране на java.io. DataInputStream; импортиране на java.io. DataOutputStream; внос java.net. InetAddress; импортиране на java.net. ServerSocket; внос java.net. Socket; публичен клас NetworkAppExample {public static void main (String args) изхвърля Exception {String host = "localhost"; int порт = 10430; ServerSocket сървър = нов ServerSocket (порт, 50, InetAddress.getByName (хост)); System.out.println ("Сървърът е стартиран."); Сокет клиент = нов гнездо (хост, порт); System.out.println ("Свързване със сървър …"); Сокет връзка = server.accept (); System.out.println ("Връзка установена."); DataOutputStream clientOut = нов DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = нов DataInputStream (client.getInputStream ()); DataOutputStream serverOut = нов DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = нов DataInputStream (connection.getInputStream ()); System.out.println ("Комуникацията е готова."); byte messageOut = "Здравей свят".getBytes (); clientOut.writeInt (messageOut.length); clientOut.write (messageOut); clientOut.flush (); System.out.println ("Съобщение изпратено до сървъра:" + нов низ (messageOut)); }}

  • Обектни потоци

    импортиране на java.io. ObjectInputStream; импортиране на java.io. ObjectOutputStream; внос java.net. InetAddress; импортиране на java.net. ServerSocket; внос java.net. Socket; публичен клас NetworkAppExample {public static void main (String args) изхвърля Exception {String host = "localhost"; int порт = 10430; ServerSocket сървър = нов ServerSocket (порт, 50, InetAddress.getByName (хост)); System.out.println ("Сървърът е стартиран."); Сокет клиент = нов сокет (хост, порт); System.out.println ("Свързване със сървър …"); Сокет връзка = server.accept (); System.out.println ("Връзка установена."); ObjectOutputStream clientOut = нов ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = нов ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = нов ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = нов ObjectInputStream (connection.getInputStream ()); System.out.println ("Комуникацията е готова."); String messageOut = "Здравей свят"; clientOut.writeObject (messageOut); clientOut.flush (); System.out.println ("Съобщение изпратено до сървъра:" + messageOut); }}

Създайте мрежово приложение в Java Step15
Създайте мрежово приложение в Java Step15

Стъпка 15. Прочетете съобщението

Прочетете данни от входния поток и ги преобразувайте. Тъй като знаем точно вида на изпратените данни, ще създадем или

Низ

от

байт

или гласове

Обект

да се

Низ

без проверка, в зависимост от използвания поток.

  • Потоци от данни

    Тъй като първоначално е изпратена дължина, а след това байтове, четенето трябва да се извършва в същия ред. В случай, че дължината е нула, няма какво да се чете. Обектът се десериализира, когато байтовете се преобразуват обратно в екземпляр, в този случай на

    Низ

    импортиране на java.io. DataInputStream; импортиране на java.io. DataOutputStream; внос java.net. InetAddress; импортиране на java.net. ServerSocket; внос java.net. Socket; публичен клас NetworkAppExample {public static void main (String args) изхвърля Exception {String host = "localhost"; int порт = 10430; ServerSocket сървър = нов ServerSocket (порт, 50, InetAddress.getByName (хост)); System.out.println ("Сървърът е стартиран."); Сокет клиент = нов сокет (хост, порт); System.out.println ("Свързване със сървър …"); Сокет връзка = server.accept (); System.out.println ("Връзка установена."); DataOutputStream clientOut = нов DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = нов DataInputStream (client.getInputStream ()); DataOutputStream serverOut = нов DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = нов DataInputStream (connection.getInputStream ()); System.out.println ("Комуникацията е готова."); byte messageOut = "Здравей свят".getBytes (); clientOut.writeInt (messageOut.length); clientOut.write (messageOut); clientOut.flush (); System.out.println ("Съобщение изпратено до сървъра:" + нов низ (messageOut)); int length = serverIn.readInt (); if (дължина> 0) {байт messageIn = нов байт [дължина]; serverIn.readFully (messageIn, 0, messageIn.length); }}}

  • Обектни потоци

    импортиране на java.io. ObjectInputStream; импортиране на java.io. ObjectOutputStream; внос java.net. InetAddress; импортиране на java.net. ServerSocket; внос java.net. Socket; публичен клас NetworkAppExample {public static void main (String args) изхвърля Exception {String host = "localhost"; int порт = 10430; ServerSocket сървър = нов ServerSocket (порт, 50, InetAddress.getByName (хост)); System.out.println ("Сървърът е стартиран."); Сокет клиент = нов сокет (хост, порт); System.out.println ("Свързване със сървър …"); Сокет връзка = server.accept (); System.out.println ("Връзка установена."); ObjectOutputStream clientOut = нов ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = нов ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = нов ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = нов ObjectInputStream (connection.getInputStream ()); System.out.println ("Комуникацията е готова."); String messageOut = "Здравей свят"; clientOut.writeObject (messageOut); clientOut.flush (); System.out.println ("Съобщение изпратено до сървъра:" + messageOut); Низ messageIn = (Низ) serverIn.readObject (); }}

Създайте мрежово приложение в Java Step16
Създайте мрежово приложение в Java Step16

Стъпка 16. Влезте в съобщението за прочетено

За целите на регистрирането отпечатайте съобщението на конзолата и получете съдържанието му.

  • Потоци от данни

    импортиране на java.io. DataInputStream; импортиране на java.io. DataOutputStream; внос java.net. InetAddress; импортиране на java.net. ServerSocket; внос java.net. Socket; публичен клас NetworkAppExample {public static void main (String args) изхвърля Exception {String host = "localhost"; int порт = 10430; ServerSocket сървър = нов ServerSocket (порт, 50, InetAddress.getByName (хост)); System.out.println ("Сървърът е стартиран."); Сокет клиент = нов сокет (хост, порт); System.out.println ("Свързване със сървър …"); Сокет връзка = server.accept (); System.out.println ("Връзка установена."); DataOutputStream clientOut = нов DataOutputStream (client.getOutputStream ()); DataInputStream clientIn = нов DataInputStream (client.getInputStream ()); DataOutputStream serverOut = нов DataOutputStream (connection.getOutputStream ()); DataInputStream serverIn = нов DataInputStream (connection.getInputStream ()); System.out.println ("Комуникацията е готова."); byte messageOut = "Здравей свят".getBytes (); clientOut.writeInt (messageOut.length); clientOut.write (messageOut); clientOut.flush (); System.out.println ("Съобщение изпратено до сървъра:" + нов низ (messageOut)); int length = serverIn.readInt (); if (дължина> 0) {байт messageIn = нов байт [дължина]; serverIn.readFully (messageIn, 0, messageIn.length); System.out.println ("Съобщение получено от клиента:" + нов низ (messageIn)); }}}

  • Обектни потоци

    импортиране на java.io. ObjectInputStream; импортиране на java.io. ObjectOutputStream; внос java.net. InetAddress; импортиране на java.net. ServerSocket; внос java.net. Socket; публичен клас NetworkAppExample {public static void main (String args) изхвърля Exception {String host = "localhost"; int порт = 10430; ServerSocket сървър = нов ServerSocket (порт, 50, InetAddress.getByName (хост)); System.out.println ("Сървърът е стартиран."); Сокет клиент = нов сокет (хост, порт); System.out.println ("Свързване със сървър …"); Сокет връзка = server.accept (); System.out.println ("Връзка установена."); ObjectOutputStream clientOut = нов ObjectOutputStream (client.getOutputStream ()); ObjectOutputStream serverOut = нов ObjectOutputStream (connection.getOutputStream ()); ObjectInputStream clientIn = нов ObjectInputStream (client.getInputStream ()); ObjectInputStream serverIn = нов ObjectInputStream (connection.getInputStream ()); System.out.println ("Комуникацията е готова."); String messageOut = "Здравей свят"; clientOut.writeObject (messageOut); clientOut.flush (); System.out.println ("Съобщение изпратено до сървъра:" + messageOut); Низ messageIn = (Низ) serverIn.readObject (); System.out.println ("Съобщение, получено от клиента:" + messageIn); }}

Създайте мрежово приложение в Java Step17
Създайте мрежово приложение в Java Step17

Стъпка 17. Прекъснете връзките

Връзката се прекъсва, когато едната страна затвори потоците си. В Java, чрез затваряне на изходния поток, съответният сокет и входният поток също се затварят. След като страна от другата страна установи, че връзката е мъртва, тя трябва да затвори и изходния си поток, за да предотврати изтичане на памет.

// код пропуснат import java.net. InetAddress; импортиране на java.net. ServerSocket; внос java.net. Socket; публичен клас NetworkAppExample {public static void main (String args) изхвърля Exception {String host = "localhost"; int порт = 10430; ServerSocket сървър = нов ServerSocket (порт, 50, InetAddress.getByName (хост)); System.out.println ("Сървърът е стартиран."); Сокет клиент = нов сокет (хост, порт); System.out.println ("Свързване със сървър …"); Сокет връзка = server.accept (); System.out.println ("Връзка установена."); // кодът е пропуснат System.out.println ("Комуникацията е готова."); // код пропуснат clientOut.close (); serverOut.close (); }}

Създайте мрежово приложение в Java Step18 V2
Създайте мрежово приложение в Java Step18 V2

Стъпка 18. Прекъсване на регистрационния файл

За целите на регистрирането връзките за печат към конзолата са прекъснати.

// код пропуснат import java.net. InetAddress; импортиране на java.net. ServerSocket; внос java.net. Socket; публичен клас NetworkAppExample {public static void main (String args) изхвърля Exception {String host = "localhost"; int порт = 10430; ServerSocket сървър = нов ServerSocket (порт, 50, InetAddress.getByName (хост)); System.out.println ("Сървърът е стартиран."); Сокет клиент = нов сокет (хост, порт); System.out.println ("Свързване със сървър …"); Сокет връзка = server.accept (); System.out.println ("Връзка установена."); // кодът е пропуснат System.out.println ("Комуникацията е готова."); // код пропуснат clientOut.close (); serverOut.close (); System.out.println ("Връзките са затворени."); }}

Създайте мрежово приложение в Java Step19
Създайте мрежово приложение в Java Step19

Стъпка 19. Прекратете сървъра

Връзките са прекъснати, но сървърът продължава да работи. Като

ServerSocket

не е свързан с никакъв поток, той трябва да бъде изрично затворен чрез извикване

близо()

метод.

// код пропуснат import java.net. InetAddress; импортиране на java.net. ServerSocket; внос java.net. Socket; публичен клас NetworkAppExample {public static void main (String args) изхвърля Exception {String host = "localhost"; int порт = 10430; ServerSocket сървър = нов ServerSocket (порт, 50, InetAddress.getByName (хост)); System.out.println ("Сървърът е стартиран."); Сокет клиент = нов сокет (хост, порт); System.out.println ("Свързване със сървър …"); Сокет връзка = server.accept (); System.out.println ("Връзка установена."); // кодът е пропуснат System.out.println ("Комуникацията е готова."); // код пропуснат clientOut.close (); serverOut.close (); System.out.println ("Връзките са затворени."); server.close (); }}

Създайте мрежово приложение в Java Step20
Създайте мрежово приложение в Java Step20

Стъпка 20. Прекратяване на сървъра за регистрация

За целите на регистрирането печатът на конзолния сървър е прекратен.

// код пропуснат import java.net. InetAddress; импортиране на java.net. ServerSocket; внос java.net. Socket; публичен клас NetworkAppExample {public static void main (String args) изхвърля Exception {String host = "localhost"; int порт = 10430; ServerSocket сървър = нов ServerSocket (порт, 50, InetAddress.getByName (хост)); System.out.println ("Сървърът е стартиран."); Сокет клиент = нов сокет (хост, порт); System.out.println ("Свързване със сървър …"); Сокет връзка = server.accept (); System.out.println ("Връзка установена."); // кодът е пропуснат System.out.println ("Комуникацията е готова."); // код пропуснат clientOut.close (); serverOut.close (); System.out.println ("Връзките са затворени."); server.close (); System.out.println ("Сървърът е прекратен."); }}

Създайте мрежово приложение в Java Step21
Създайте мрежово приложение в Java Step21

Стъпка 21. Компилирайте и стартирайте

Регистрирането ни позволи да разберем дали приложението е било успешно или не. Очакван резултат:

Сървърът стартира. Свързване към сървъра … Връзката е установена. Комуникацията е готова. Съобщение, изпратено до сървъра: Hello World Съобщение, получено от клиента: Hello World Connections затворени. Сървърът е прекратен.

В случай, че вашият изход не е като този по -горе, което е малко вероятно да се случи, има няколко решения:

  • Ако изходът спре на линията

    Установена е връзка.

    и се използват потоци от обекти, всеки се промива

    ObjectOutputStream

  • веднага след инициализацията, тъй като по някаква причина заглавките не са изпратени.
  • Ако изходът се отпечата

    java.net. BindException: Адресът вече се използва

  • изберете различен номер на порт, защото посоченият вече е използван.

Съвети

  • Свързването към сървър в друга мрежа се осъществява чрез свързване към външния IP адрес на устройство, работещо със сървъра, който има пренасочен порт.
  • Свързването към сървър в същата мрежа става чрез свързване към частния IP адрес на устройство, работещо на сървъра, или препращане на порт и свързване към външния IP адрес на устройството.
  • Има софтуер, като Hamachi, който позволява свързване към сървъра в различна мрежа, без да се препраща порт, но изисква инсталиране на софтуера и на двете устройства.

Примери

Мрежовите приложения, които използват блокиране на вход/изход, трябва да използват нишки. Следващите примери показват минималистично изпълнение на сървър и клиент с нишки. Кодът за работа по същество е същият като в статията, с изключение на това, че някои фрагменти са синхронизирани, преместени в нишки и се обработват изключения.

Server.java

импортиране на java.io. IOException; внос java.net. InetAddress; импортиране на java.net. ServerSocket; импортиране на java.net. SocketException; import java.net. UnknownHostException; импортиране на java.util. ArrayList; импортиране на java.util. Collections; импортиране на java.util. List; /*** Класът {@code Server} представлява крайна точка на сървър в мрежа. {@code Server} веднъж свързан с определен IP * адрес и порт, установява връзки с клиенти и може да комуникира с тях или да ги прекъсне. *

* Този клас е безопасен за нишките. * * @version 1.0 * @see Client * @see Connection */ публичен клас Сървърът изпълнява Runnable {private ServerSocket сървър; частен списък връзки; частна нишка; частен окончателен обект връзкиLock = нов обект (); /** * Конструира {@code сървър}, който взаимодейства с клиенти на посоченото име и порт на хоста с посочената * поискана максимална дължина на опашка от входящи клиенти. * * @param хост Адрес на хоста за използване. * @param порт Номер на порта за използване. * @param backlog Заявена максимална дължина на опашката от входящи клиенти. * @throws NetworkException Ако възникне грешка при стартиране на сървър. */ публичен сървър (String host, int port, int backlog) изхвърля NetworkException {try {server = new ServerSocket (port, backlog, InetAddress.getByName (host)); } catch (UnknownHostException e) {throw new NetworkException ("Името на хоста не може да бъде разрешено:" + хост, д); } catch (IllegalArgumentException e) {throw new NetworkException ("Номерът на порта трябва да бъде между 0 и 65535 (включително):" + порт); } catch (IOException e) {throw new NetworkException ("Сървърът не може да бъде стартиран.", д); } връзки = Collections.synchronizedList (нов ArrayList ()); нишка = нова нишка (това); thread.start (); } /*** Конструира {@code сървър}, който взаимодейства с клиенти на посоченото име и порт на хост. * * @param хост Адрес на хоста за свързване. * @param port Номер на порт за свързване. * @throws NetworkException Ако възникнат грешки при стартиране на сървър. */ публичен сървър (низов хост, int порт) изхвърля NetworkException {this (хост, порт, 50); } /*** Слуша, приема и регистрира входящи връзки от клиенти. */ @Override public void run () {while (! Server.isClosed ()) {try {connections.add (нова връзка (server.accept ())); } catch (SocketException e) {if (! e.getMessage (). equals ("Socket closed")) {e.printStackTrace (); }} catch (NetworkException | IOException e) {e.printStackTrace (); }}} /*** Изпраща данни до всички регистрирани клиенти. * * @param данни Данни за изпращане. * @throws IllegalStateException Ако се опита запис на данни, когато сървърът е офлайн. * @throws IllegalArgumentException Ако данните за изпращане са нулеви. */ публично недействително излъчване (Обектни данни) {if (server.isClosed ()) {хвърли ново IllegalStateException ("Данните не са изпратени, сървърът е офлайн."); } if (data == null) {throw new IllegalArgumentException ("null data"); } синхронизиран (connectionsLock) {за (Връзка връзка: връзки) {опитайте {connection.send (данни); System.out.println ("Данните са изпратени до клиента успешно."); } catch (NetworkException e) {e.printStackTrace (); }}}} /*** Изпраща съобщение за прекъсване и изключва посочения клиент. * * @param връзка Клиент за прекъсване. * @throws NetworkException Ако възникне грешка при прекъсване на връзката. */ public void disconnect (Connection connection) изхвърля NetworkException {if (connections.remove (connection)) {connection.close (); }} /*** Изпраща съобщение за изключване до всички клиенти, прекъсва връзката им и прекратява сървъра. */ public void close () изхвърля NetworkException {synchronized (connectionsLock) {for (Connection connection: connections) {try {connection.close (); } catch (NetworkException e) {e.printStackTrace (); }}} links.clear (); опитайте {server.close (); } catch (IOException e) {throw new NetworkException ("Грешка при затваряне на сървъра."); } накрая {thread.interrupt (); }} /*** Връща дали сървърът е онлайн или не. * * @return Вярно, ако сървърът е онлайн. Фалшиво, иначе. */ публично логическо isOnline () {return! server.isClosed (); } /*** Връща масив от регистрирани клиенти. */ public Connection getConnections () {synchronized (connectionsLock) {връщане на връзки.toArray (нова връзка [connections.size ()]); }}}

Client.java

импортиране на java.io. IOException; внос java.net. Socket; import java.net. UnknownHostException; /*** Класът {@code Client} представлява клиентска крайна точка в мрежа. {@code Client}, веднъж свързан с определен * сървър, гарантирано ще може да комуникира само със сървъра. Дали други клиенти ще получат данните * или не, зависи от изпълнението на сървъра. *

* Този клас е безопасен за нишки. * * @версия 1.0 * @виж сървър * @виж връзка */ публичен клас клиент {частна връзка връзка; /*** Конструира {@code Client}, свързан със сървъра на посочения хост и порт. * * @param хост Адрес на хоста за свързване. * @param port Номер на порт за свързване. * @throws NetworkException Ако възникне грешка при стартиране на сървър. */ публичен клиент (низов хост, int порт) изхвърля NetworkException {try {connection = new Connection (нов сокет (хост, порт)); } catch (UnknownHostException e) {throw new NetworkException ("Името на хоста не може да бъде разрешено:" + хост, д); } catch (IllegalArgumentException e) {throw new NetworkException ("Номерът на порта трябва да бъде между 0 и 65535 (включително):" + порт); } catch (IOException e) {throw new NetworkException ("Сървърът не може да бъде стартиран.", д); }} /*** Изпраща данни на другата страна. * * @param данни Данни за изпращане. * @throws NetworkException Ако записването към изходния поток е неуспешно. * @throws IllegalStateException Ако се опита запис на данни при затваряне на връзката. * @throws IllegalArgumentException Ако данните за изпращане са нулеви. * @throws UnsupportedOperationException Ако се опита да се изпрати неподдържан тип данни. */ public void send (Object data) изхвърля NetworkException {connection.send (data); } /*** Изпраща съобщение за прекъсване на връзката със сървъра и затваря. */ public void close () хвърля NetworkException {connection.close (); } /*** Връща дали клиентът е свързан със сървъра. * * @return Вярно, ако клиентът е свързан. Фалшиво, иначе. */ публично логическо isOnline () {връщане на връзката.isConnected (); } /*** Връща екземпляра {@link Connection} на клиента. */ обществена връзка getConnection () {връщане на връзката; }}

Connection.java

импортиране на java.io. DataInputStream; импортиране на java.io. DataOutputStream; импортиране на java.io. IOException; внос java.net. Socket; импортиране на java.net. SocketException; /** * Класът {@code Connection} представлява или връзка от сървър към клиент, или клиентска крайна точка в мрежа * * {@code Connection}, след като е свързан, е в състояние да обменя данни с друга страна или страни, в зависимост от на сървър * реализация. *

* Този клас е безопасен за нишки. * * @версия 1.0 * @see сървър * @see клиент */ публичен клас Връзката изпълнява Runnable {private Socket socket; частен DataOutputStream out; частен DataInputStream в; частна нишка; частен окончателен обект writeLock = нов обект (); частен окончателен обект readLock = нов обект (); /*** Конструира {@code Connection}, използвайки потоци от посочен {@link Socket}. * * @param гнездо Сокет за извличане на потоците от.*/ public Connection (Socket socket) изхвърля NetworkException {if (socket == null) {throw new IllegalArgumentException ("null socket"); } this.socket = гнездо; опитайте {out = new DataOutputStream (socket.getOutputStream ()); } catch (IOException e) {throw new NetworkException ("Не можах да получа достъп до изходния поток.", д); } опитайте {in = new DataInputStream (socket.getInputStream ()); } catch (IOException e) {throw new NetworkException ("Не можах да получа достъп до входния поток.", д); } нишка = нова нишка (това); thread.start (); } /*** Чете съобщения, докато връзката с другата страна е жива. */ @Override public void run () {while (! Socket.isClosed ()) {try {int identifier; байт байтове; синхронизиран (readLock) {идентификатор = in.readInt (); int length = in.readInt (); if (дължина> 0) {байтове = нов байт [дължина]; in.readFully (байтове, 0, байтове.дължина); } else {продължи; }} превключвател (идентификатор) {идентификатор на случай. INTERNAL: Команда за низ = нов низ (байтове); if (command.equals ("прекъсване на връзката")) {if (! socket.isClosed ()) {System.out.println ("Получен пакет за изключване."); опитайте {close (); } catch (NetworkException e) {return; }}} почивка; регистър идентификатор. TEXT: System.out.println ("Получено съобщение:" + нов низ (байтове)); прекъсване; по подразбиране: System.out.println ("Получени неразпознати данни."); }} catch (SocketException e) {if (! e.getMessage (). equals ("Socket closed")) {e.printStackTrace (); }} catch (IOException e) {e.printStackTrace (); }}} /*** Изпраща данни на другата страна. * * @param данни Данни за изпращане. * @throws NetworkException Ако записването към изходния поток е неуспешно. * @throws IllegalStateException Ако се опита запис на данни при затваряне на връзката. * @throws IllegalArgumentException Ако данните за изпращане са нулеви. * @throws UnsupportedOperationException Ако се опита да се изпрати неподдържан тип данни. */ public void send (Object data) изхвърля NetworkException {if (socket.isClosed ()) {throw new IllegalStateException ("Данните не са изпратени, връзката е затворена."); } if (data == null) {throw new IllegalArgumentException ("null data"); } int идентификатор; байт байтове; if (data instanceof String) {identifier = Identifier. TEXT; байтове = (((Низови) данни)).getBytes (); } else {throw new UnsupportedOperationException ("Неподдържан тип данни:" + data.getClass ()); } опитайте {synchronized (writeLock) {out.writeInt (идентификатор); out.writeInt (bytes.length); out.write (байтове); out.flush (); }} catch (IOException e) {throw new NetworkException ("Данните не могат да бъдат изпратени.", д); }} /*** Изпраща съобщение за прекъсване на връзката с другата страна и затваря връзката с нея. */ public void close () хвърля NetworkException {if (socket.isClosed ()) {хвърля ново IllegalStateException ("Връзката вече е затворена."); } опитайте {byte message = "прекъснете връзката".getBytes (); синхронизиран (writeLock) {out.writeInt (Identifier. INTERNAL); out.writeInt (message.length); out.write (съобщение); out.flush (); }} catch (IOException e) {System.out.println ("Съобщението за прекъсване не може да бъде изпратено."); } опитайте {synchronized (writeLock) {out.close (); }} catch (IOException e) {throw new NetworkException ("Грешка при прекъсване на връзката.", д); } накрая {thread.interrupt (); }} /*** Връща дали връзката с другата страна е жива. * * @return Вярно, ако връзката е жива. Фалшиво, иначе. */ публично логическо isConnected () {return! socket.isClosed (); }}

Идентификатор.java

/** * Класът {@code Identifier} съдържа константи, използвани от {@link Connection} за сериализиране и десериализиране на данните *, изпратени по мрежата. * * @версия 1.0 * @вижте Връзка * / публичен идентификатор на крайния клас { / ** * Идентификатор за вътрешни съобщения. */ публичен статичен краен int INTERNAL = 1; /*** Идентификатор за текстови съобщения. */ публичен статичен краен int TEXT = 2; }

NetworkException.java

/*** Класът {@code NetworkException} показва грешка, свързана с мрежата. * / публичен клас NetworkException разширява Exception { / *** Конструира {@code NetworkException} с {@code null} като съобщение. * / public NetworkException () {} / *** Конструира {@code NetworkException} с посоченото съобщение. * * @param съобщение Съобщение за описване на грешка. */ обществено NetworkException (низово съобщение) {супер (съобщение); } /*** Конструира {@code NetworkException} с посоченото съобщение и причина. * * @param съобщение Съобщение за описване на грешка. * @param причина Причина за грешка. */ public NetworkException (Низово съобщение, Throwable кауза) {супер (съобщение, причина); } /*** Конструира {@code NetworkException} с посочената причина. * * @param причина Причина за грешка. */ public NetworkException (Throwable кауза) {super (причина); }}

UsageExample.java

/*** Класът {@code UsageExample} показва използването на {@link Server} и {@link Client}. В тези примери се използва * {@link Thread#sleep (long)}, за да се гарантира, че всеки сегмент се изпълнява, защото бързото стартиране и затваряне кара някои * сегменти да не се изпълняват. * * @version 1.0 * @see Server * @see Client */ публичен клас UsageExample {public static void main (String args) изхвърля Exception {String host = "localhost"; int порт = 10430; Сървър сървър = нов сървър (хост, порт); Клиент клиент = нов клиент (хост, порт); Thread.sleep (100L); client.send ("Здравейте."); server.broadcast ("Хей, приятелю!"); Thread.sleep (100L); server.disconnect (server.getConnections () [0]); // или client.close () за прекъсване на връзката от клиентската страна server.close (); }}

Препоръчано: