{"id":36378,"date":"2019-10-31T22:11:20","date_gmt":"2019-10-31T19:11:20","guid":{"rendered":"https:\/\/prohoster.info\/blog\/napisanie-programmnogo-obespecheniya-s-funktsionalom-klient-servernyh-utilit-windows-part-01\/"},"modified":"2019-10-31T22:11:20","modified_gmt":"2019-10-31T19:11:20","slug":"napisanie-programmnogo-obespecheniya-s-funktsionalom-klient-servernyh-utilit-windows-part-01","status":"publish","type":"post","link":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/napisanie-programmnogo-obespecheniya-s-funktsionalom-klient-servernyh-utilit-windows-part-01","title":{"rendered":"Pisanie oprogramowania z funkcjonalno\u015bci\u0105 klient-serwer w systemie Windows, cz\u0119\u015b\u0107 01","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Witam.<\/p>\n<p>Dzi\u015b chcia\u0142bym om\u00f3wi\u0107 proces pisania aplikacji kliencko-serwerowych, kt\u00f3re wykonuj\u0105 funkcje standardowych narz\u0119dzi systemu Windows, takich jak Telnet, TFTP i tak dalej, w czystej Javie. Oczywi\u015bcie nie wnosz\u0119 nic nowego \u2014 wszystkie te narz\u0119dzia dzia\u0142aj\u0105 ju\u017c od lat, ale my\u015bl\u0119, \u017ce nie wszyscy wiedz\u0105, co dzieje si\u0119 pod powierzchni\u0105.<\/p>\n<p>W\u0142a\u015bnie o tym b\u0119dzie mowa w dalszej cz\u0119\u015bci artyku\u0142u. <br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><br \/>\nW tym artykule, aby go nie przed\u0142u\u017ca\u0107, opr\u00f3cz og\u00f3lnych informacji opisz\u0119 tylko serwer Telnet, ale na ten moment mam te\u017c materia\u0142y o innych narz\u0119dziach \u2014 b\u0119dzie to w kolejnych cz\u0119\u015bciach cyklu.<\/p>\n<p>Przede wszystkim warto wyja\u015bni\u0107, czym w\u0142a\u015bciwie jest Telnet, do czego s\u0142u\u017cy i jak go u\u017cywa\u0107. Nie b\u0119d\u0119 dos\u0142ownie cytowa\u0107 \u017ar\u00f3de\u0142 (je\u015bli trzeba \u2014 na ko\u0144cu artyku\u0142u do\u0142\u0105cz\u0119 linki do materia\u0142\u00f3w w temacie), powiem tylko, \u017ce Telnet zapewnia zdalny dost\u0119p do wiersza polece\u0144 urz\u0105dzenia. W zasadzie to jego funkcjonalno\u015b\u0107 si\u0119 ko\u0144czy (o zwracaniu do portu serwera nie wspomnia\u0142em \u015bwiadomie, o tym p\u00f3\u017aniej). Oznacza to, \u017ce do jego realizacji musimy odebra\u0107 ci\u0105g na kliencie, przekaza\u0107 go do serwera, spr\u00f3bowa\u0107 przekaza\u0107 go do wiersza polece\u0144, odczyta\u0107 odpowied\u017a z wiersza polece\u0144, je\u015bli taka istnieje, przekaza\u0107 j\u0105 z powrotem do klienta i wy\u015bwietli\u0107 na ekranie, lub w przypadku wyst\u0105pienia b\u0142\u0119du da\u0107 u\u017cytkownikowi zna\u0107, \u017ce co\u015b posz\u0142o nie tak.<\/p>\n<p>Aby zrealizowa\u0107 powy\u017csze, potrzebujemy odpowiednio dw\u00f3ch klas roboczych oraz klasy testowej, z kt\u00f3rej uruchomimy serwer i przez kt\u00f3r\u0105 b\u0119dzie dzia\u0142a\u0142 klient.<br \/>\nObecnie struktura aplikacji obejmuje:<\/p>\n<ul>\n<li>TelnetClient<\/li>\n<li>TelnetClientTester<\/li>\n<li>TelnetServer<\/li>\n<li>TelnetServerTester<\/li>\n<\/ul>\n<p>\nPrzejd\u017amy do ka\u017cdej z nich:<\/p>\n<p><b>TelnetClient<\/b><\/p>\n<p>Wszystko, co ten klas musi umie\u0107, to wysy\u0142a\u0107 otrzymane polecenia i pokazywa\u0107 otrzymane odpowiedzi. Ponadto musi umie\u0107 \u0142\u0105czy\u0107 si\u0119 z dowolnym (o czym wspomnia\u0142em powy\u017cej) portem zdalnego urz\u0105dzenia i roz\u0142\u0105cza\u0107 si\u0119 z nim.<\/p>\n<p>W tym celu zaimplementowano nast\u0119puj\u0105ce funkcje:<\/p>\n<p>Funkcja, kt\u00f3ra przyjmuje jako argument adres gniazda, otwiera po\u0142\u0105czenie i uruchamia strumienie wej\u015bcia i wyj\u015bcia (zmienne strumieni s\u0105 zadeklarowane powy\u017cej, pe\u0142ne \u017ar\u00f3d\u0142a \u2014 na ko\u0144cu artyku\u0142u).<\/p>\n<pre><code class=\"java\"> public void run(String ip, int port)\n    {\n        try {\n            Socket socket = new Socket(ip, port);\n            InputStream sin = socket.getInputStream();\n            OutputStream sout = socket.getOutputStream();\n            Scanner keyboard = new Scanner(System.in);\n            reader = new Thread(() -&gt; read(keyboard, sout));\n            writer = new Thread(() -&gt; write(sin));\n            reader.start();\n            writer.start();\n        }\n        catch (Exception e) {\n            System.out.println(e.getMessage());\n        }\n    }\n<\/code><\/pre>\n<p>\nPrzeci\u0105\u017cenie tej samej funkcji, kt\u00f3re \u0142\u0105czy si\u0119 z domy\u015blnym portem \u2014 dla telnetu to 23<\/p>\n<pre><code class=\"java\">\n    public void run(String ip)\n    {\n        run(ip, 23);\n    }\n<\/code><\/pre>\n<p>\nFunkcja odczytuje znaki z klawiatury i przesy\u0142a je do wyj\u015bciowego gniazda \u2014 co jest charakterystyczne, w trybie liniowym, a nie znakowym:<\/p>\n<pre><code class=\"java\">\n    private void read(Scanner keyboard, OutputStream sout)\n    {\n        try {\n            String input = new String();\n            while (true) {\n                input = keyboard.nextLine();\n                for (char i : (input + \" n\").toCharArray())\n                    sout.write(i);\n            }\n        }\n        catch (Exception e) {\n            System.out.println(e.getMessage());\n        }\n    }\n<\/code><\/pre>\n<p>\nFunkcja odbiera dane z gniazda i wy\u015bwietla je na ekranie<\/p>\n<pre><code class=\"java\">\n    private void write(InputStream sin)\n    {\n        try {\n            int tmp;\n            while (true){\n                tmp = sin.read();\n                System.out.print((char)tmp);\n            }\n        }\n        catch (Exception e) {\n            System.out.println(e.getMessage());\n        }\n    }\n<\/code><\/pre>\n<p>\nFunkcja zatrzymuje odbi\u00f3r i przesy\u0142anie danych<\/p>\n<pre><code class=\"java\">\n    public void stop()\n    {\n        reader.stop();\n        writer.stop();\n    }\n}<\/code><\/pre>\n<p>\n<b>TelnetServer<\/b><\/p>\n<p>Ta klasa powinna mie\u0107 funkcjonalno\u015b\u0107 przyjmowania polecenia z gniazda, wysy\u0142ania go do wykonania i przesy\u0142ania odpowiedzi z powrotem do gniazda. W programie celowo nie ma sprawdzania danych wej\u015bciowych, poniewa\u017c po pierwsze, w \u201epude\u0142kowym telnecie\u201d istnieje mo\u017cliwo\u015b\u0107 sformatowania dysku serwera, a po drugie, kwestia bezpiecze\u0144stwa w tym artykule jest pomini\u0119ta, dlatego nie ma ani s\u0142owa o szyfrowaniu lub SSL.<\/p>\n<p>Tutaj s\u0105 tylko 2 funkcje (jedna z nich jest przeci\u0105\u017cona), i og\u00f3lnie nie jest to najlepsza praktyka, jednak w ramach tego zadania uzna\u0142em, \u017ce warto zostawi\u0107 wszystko, jak jest.<\/p>\n<pre><code class=\"java\"> boolean isRunning = true;\n    public void run(int port)    {\n\n        (new Thread(()-&gt;{ try {\n            ServerSocket ss = new ServerSocket(port); \/\/ tworzymy gniazdo serwera i przypisujemy je do podanego portu\n            System.out.println(\"Port \"+port+\" oczekuje na po\u0142\u0105czenia\");\n\n            Socket socket = ss.accept();\n            System.out.println(\"Po\u0142\u0105czono\");\n            System.out.println();\n\n            \/\/ Pobieramy strumienie wej\u015bciowe i wyj\u015bciowe gniazda, teraz mo\u017cemy odbiera\u0107 i wysy\u0142a\u0107 dane do klienta.\n            InputStream sin = socket.getInputStream();\n            OutputStream sout = socket.getOutputStream();\n\n            Map env = System.getenv();\n            String wayToTemp = env.get(\"TEMP\") + \"tmp.txt\";\n            for (int i : (\"Connectednnr\".toCharArray()))\n                sout.write(i);\n            sout.flush();\n\n            String buffer = new String();\n            while (isRunning) {\n\n                int intReader = 0;\n                while ((char) intReader != 'n') {\n                    intReader = sin.read();\n                    buffer += (char) intReader;\n                }\n\n\n                final String inputToSubThread = \"cmd \/c \" + buffer.substring(0, buffer.length()-2) + \" 2&gt;&amp;1\";\n\n\n                new Thread(() -&gt; {\n                    try {\n\n                        Process p = Runtime.getRuntime().exec(inputToSubThread);\n                        InputStream out = p.getInputStream();\n                        Scanner fromProcess = new Scanner(out);\n                        try {\n\n                            while (fromProcess.hasNextLine()) {\n                                String temp = fromProcess.nextLine();\n                                System.out.println(temp);\n                                for (char i : temp.toCharArray())\n                                    sout.write(i);\n                                sout.write('n');\n                                sout.write('r');\n                            }\n                        }\n                        catch (Exception e) {\n                            String output = \"Co\u015b posz\u0142o nie tak... Kod b\u0142\u0119du: \" + e.getStackTrace();\n                            System.out.println(output);\n                            for (char i : output.toCharArray())\n                                sout.write(i);\n                            sout.write('n');\n                            sout.write('r');\n                        }\n\n                        p.getErrorStream().close();\n                        p.getOutputStream().close();\n                        p.getInputStream().close();\n                        sout.flush();\n\n                    }\n                    catch (Exception e) {\n                        System.out.println(\"B\u0142\u0105d: \" + e.getMessage());\n                    }\n                }).start();\n                System.out.println(buffer);\n                buffer = \"\";\n\n            }\n        }\n        catch(Exception x) {\n            System.out.println(x.getMessage());\n        }})).start();\n\n    }\n<\/code><\/pre>\n<p>\nProgram otwiera port serwera, odczytuje z niego dane, a\u017c natrafi na znak ko\u0144ca komendy, nast\u0119pnie przekazuje komend\u0119 do nowego procesu, a wyj\u015bcie z procesu jest przekierowywane do gniazda. Proste jak automat ka\u0142asznikowa.<\/p>\n<p>Odpowiednio, dla tej funkcji istnieje przeci\u0105\u017cenie z domy\u015blnym portem:<\/p>\n<pre><code class=\"java\"> public void run()\n    {\n        run(23);\n    }<\/code><\/pre>\n<p>\nNo i odpowiednio, funkcja zatrzymuj\u0105ca serwer \u2014 te\u017c wszystko trywialne, przerywa wieczn\u0105 p\u0119tl\u0119, naruszaj\u0105c jej warunek.<\/p>\n<pre><code class=\"java\">    public void stop()\n    {\n        System.out.println(\"Serwer zosta\u0142 zatrzymany\");\n        this.isRunning = false;\n    }<\/code><\/pre>\n<p>\nNie b\u0119d\u0119 tu przytacza\u0107 klas testowych, s\u0105 na dole \u2014 wszystko, co robi\u0105, to sprawdzaj\u0105 dzia\u0142anie publicznych metod. Wszystko znajduje si\u0119 na gicie.<\/p>\n<p>Podsumowuj\u0105c, w ci\u0105gu kilku wieczor\u00f3w mo\u017cna zrozumie\u0107 zasady dzia\u0142ania podstawowych narz\u0119dzi konsolowych. Teraz, gdy po\u0142\u0105czymy si\u0119 z zdalnym komputerem, rozumiemy, co si\u0119 dzieje \u2014 magia znikn\u0119\u0142a)<\/p>\n<p>A zatem, linki:<br \/>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/Toxa-p07a1330\/Temviewer\">Wszystkie \u017ar\u00f3d\u0142a by\u0142y, s\u0105 i b\u0119d\u0105 tutaj<\/a><\/noindex><br \/>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/www.extrahop.com\/resources\/protocols\/telnet\/\">O Telnecie<\/a><\/noindex><br \/>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/www.lifewire.com\/what-does-telnet-do-2483642\">Jeszcze o Telnecie<\/a><\/noindex><br \/>\n<br \/>\u0179r\u00f3d\u0142o: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/460569\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041f\u0440\u0438\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e. \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043a\u043b\u0438\u0435\u043d\u0442-\u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0449\u0438\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0445 \u0443\u0442\u0438\u043b\u0438\u0442 Windows, \u043a\u0430\u043a \u0442\u043e Telnet, TFTP, et cetera, et cetera \u043d\u0430 \u0447\u0438\u0441\u0442\u043e\u0439 Jav\u0430. \u041f\u043e\u043d\u044f\u0442\u043d\u043e, \u0447\u0442\u043e \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u043e\u0432\u043e\u0433\u043e \u044f \u043d\u0435 \u043f\u0440\u0438\u0432\u043d\u0435\u0441\u0443 \u2014 \u0432\u0441\u0435 \u044d\u0442\u0438 \u0443\u0442\u0438\u043b\u0438\u0442\u044b \u0443\u0436\u0435 \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u043d\u0435 \u043e\u0434\u0438\u043d \u0433\u043e\u0434, \u043d\u043e, \u043f\u043e\u043b\u0430\u0433\u0430\u044e, \u0447\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c \u0443 \u043d\u0438\u0445 \u0437\u043d\u0430\u044e\u0442 \u043d\u0435 \u0432\u0441\u0435. \u0418\u043c\u0435\u043d\u043d\u043e \u043e\u0431 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-36378","post","type-post","status-publish","format-standard","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041f\u0440\u0438\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e. \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043a\u043b\u0438\u0435\u043d\u0442-\u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0449\u0438\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0445 \u0443\u0442\u0438\u043b\u0438\u0442 Windows, \u043a\u0430\u043a \u0442\u043e Telnet, TFTP, et cetera, et cetera \u043d\u0430 \u0447\u0438\u0441\u0442\u043e\u0439 Jav\u0430.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/napisanie-programmnogo-obespecheniya-s-funktsionalom-klient-servernyh-utilit-windows-part-01\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"pl_PL\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e\u0433\u043e \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0435\u043d\u0438\u044f \u0441 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u043e\u043c \u043a\u043b\u0438\u0435\u043d\u0442-\u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0445 \u0443\u0442\u0438\u043b\u0438\u0442 Windows, part 01 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041f\u0440\u0438\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e. \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043a\u043b\u0438\u0435\u043d\u0442-\u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0449\u0438\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0445 \u0443\u0442\u0438\u043b\u0438\u0442 Windows, \u043a\u0430\u043a \u0442\u043e Telnet, TFTP, et cetera, et cetera \u043d\u0430 \u0447\u0438\u0441\u0442\u043e\u0439 Jav\u0430.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/napisanie-programmnogo-obespecheniya-s-funktsionalom-klient-servernyh-utilit-windows-part-01\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T19:11:20+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T19:11:20+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Pisanie oprogramowania z funkcjonalno\u015bci\u0105 klient-serwerowych narz\u0119dzi Windows, cz\u0119\u015b\u0107 01 | ProHoster","description":"Witam. Dzi\u015b chcia\u0142bym om\u00f3wi\u0107 proces pisania aplikacji kliencko-serwerowych, pe\u0142ni\u0105cych funkcje standardowych narz\u0119dzi Windows, takich jak Telnet, TFTP, itd., itd. w czystej Javie.","canonical_url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/napisanie-programmnogo-obespecheniya-s-funktsionalom-klient-servernyh-utilit-windows-part-01","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"pl_PL","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e\u0433\u043e \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0435\u043d\u0438\u044f \u0441 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u043e\u043c \u043a\u043b\u0438\u0435\u043d\u0442-\u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0445 \u0443\u0442\u0438\u043b\u0438\u0442 Windows, part 01 | ProHoster","og:description":"\u041f\u0440\u0438\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e. \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043a\u043b\u0438\u0435\u043d\u0442-\u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0449\u0438\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0445 \u0443\u0442\u0438\u043b\u0438\u0442 Windows, \u043a\u0430\u043a \u0442\u043e Telnet, TFTP, et cetera, et cetera \u043d\u0430 \u0447\u0438\u0441\u0442\u043e\u0439 Jav\u0430.","og:url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/napisanie-programmnogo-obespecheniya-s-funktsionalom-klient-servernyh-utilit-windows-part-01","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T19:11:20+00:00","article:modified_time":"2019-10-31T19:11:20+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"36378","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-22 03:04:19","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 01:46:25","updated":"2026-01-22 03:04:19","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/36378","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/comments?post=36378"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/36378\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media?parent=36378"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/categories?post=36378"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/tags?post=36378"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}