වින්ඩෝස් සේවාදායක-සේවාදායක උපයෝගිතා වල ක්‍රියාකාරීත්වය සහිත ලිවීමේ මෘදුකාංග, 01 කොටස

සුභ පැතුම්.

අද මම පිරිසිදු ජාවා තුළ Telnet, TFTP, et cetera, et cetera වැනි සම්මත වින්ඩෝස් උපයෝගිතා වල කාර්යයන් ඉටු කරන සේවාදායක-සේවාදායක යෙදුම් ලිවීමේ ක්‍රියාවලිය දෙස බැලීමට කැමතියි. මම අලුත් කිසිවක් ගෙන නොයන බව පැහැදිලිය - මෙම සියලු උපයෝගිතා වසරකට වැඩි කාලයක් සාර්ථකව ක්‍රියාත්මක වේ, නමුත් ආවරණය යටතේ සිදුවන්නේ කුමක්ද යන්න සෑම දෙනාම නොදන්නා බව මම විශ්වාස කරමි.

කප්පාදුව යටතේ සාකච්ඡා කරනු ලබන්නේ මෙයයි.

මෙම ලිපියෙන්, එය ඇදගෙන නොයනු පිණිස, සාමාන්ය තොරතුරු වලට අමතරව, මම Telnet සේවාදායකය ගැන පමණක් ලියන්නෙමි, නමුත් මේ මොහොතේ වෙනත් උපයෝගිතා පිළිබඳ ද්රව්ය ද ඇත - එය මාලාවේ තවත් කොටස්වල ඇත.

පළමුවෙන්ම, ඔබ Telnet යනු කුමක්ද, එය අවශ්ය වන්නේ කුමක්ද සහ එය භාවිතා කරන්නේ කුමක් සඳහාද යන්න සොයා බැලිය යුතුය. මම මූලාශ්‍ර වාචිකව උපුටා දක්වන්නේ නැත (අවශ්‍ය නම්, ලිපියේ අවසානයේ මාතෘකාව පිළිබඳ ද්‍රව්‍ය වෙත සබැඳියක් අමුණන්නෙමි), ටෙල්නෙට් උපාංගයේ විධාන රේඛාවට දුරස්ථ ප්‍රවේශය ලබා දෙන බව පමණක් කියමි. විශාල වශයෙන්, එහි ක්‍රියාකාරීත්වය අවසන් වන්නේ මෙතැනින්ය (සේවාදායක වරායට ප්‍රවේශ වීම ගැන මම හිතාමතාම නිහඬව සිටියෙමි; ඒ ගැන වැඩි විස්තර පසුව). මෙයින් අදහස් කරන්නේ එය ක්‍රියාත්මක කිරීම සඳහා, අපි සේවාදායකයා මත රේඛාවක් පිළිගත යුතුය, එය සේවාදායකයට යැවීමට, එය විධාන රේඛාවට යැවීමට උත්සාහ කළ යුතුය, විධාන රේඛා ප්‍රතිචාරය කියවිය යුතුය, එකක් තිබේ නම්, එය නැවත සේවාදායකයාට ලබා දිය යුතුය. එය තිරය මත ප්රදර්ශනය කරන්න, හෝ, දෝෂ තිබේ නම්, යමක් වැරදි බව පරිශීලකයාට දන්වන්න.

ඉහත ක්‍රියාත්මක කිරීම සඳහා, ඒ අනුව, අපට වැඩ කරන පන්ති 2 ක් සහ පරීක්ෂණ පන්තියක් අවශ්‍ය වේ, එයින් අපි සේවාදායකය දියත් කරන අතර සේවාදායකයා ක්‍රියා කරනු ඇත.
ඒ අනුව, මේ මොහොතේ යෙදුම් ව්‍යුහයට ඇතුළත් වන්නේ:

  • TelnetClient
  • TelnetClientTester
  • TelnetServer
  • TelnetServerTester

අපි ඒ එක් එක් හරහා යමු:

TelnetClient

මෙම පන්තියට කළ හැක්කේ ලැබුණු විධාන යැවීම සහ ලැබුණු ප්‍රතිචාර පෙන්වීම පමණි. මීට අමතරව, දුරස්ථ උපාංගයක අත්තනෝමතික (ඉහත සඳහන් කළ පරිදි) වරායකට සම්බන්ධ වීමට සහ එයින් විසන්ධි කිරීමට ඔබට හැකි විය යුතුය.

මෙය සාක්ෂාත් කර ගැනීම සඳහා, පහත සඳහන් කාර්යයන් ක්රියාත්මක කරන ලදී:

සොකට් ලිපිනයක් තර්කයක් ලෙස ගන්නා ශ්‍රිතයක්, සම්බන්ධතාවයක් විවෘත කර ආදාන සහ ප්‍රතිදාන ප්‍රවාහයන් ආරම්භ කරයි (ප්‍රවාහ විචල්‍යයන් ඉහත ප්‍රකාශ කර ඇත, සම්පූර්ණ මූලාශ්‍ර ලිපියේ අවසානයේ ඇත).

 public void run(String ip, int port)
    {
        try {
            Socket socket = new Socket(ip, port);
            InputStream sin = socket.getInputStream();
            OutputStream sout = socket.getOutputStream();
            Scanner keyboard = new Scanner(System.in);
            reader = new Thread(()->read(keyboard, sout));
            writer = new Thread(()->write(sin));
            reader.start();
            writer.start();
        }
        catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

එකම කාර්යය අධික ලෙස පැටවීම, පෙරනිමි වරායට සම්බන්ධ කිරීම - ටෙල්නෙට් සඳහා මෙය 23 කි


    public void run(String ip)
    {
        run(ip, 23);
    }

ශ්‍රිතය යතුරුපුවරුවෙන් අක්ෂර කියවා ඒවා ප්‍රතිදාන සොකට් වෙත යවයි - එය සාමාන්‍ය, රේඛීය ප්‍රකාරයේදී, අක්ෂර මාදිලියේ නොවේ:


    private void read(Scanner keyboard, OutputStream sout)
    {
        try {
            String input = new String();
            while (true) {
                input = keyboard.nextLine();
                for (char i : (input + " n").toCharArray())
                    sout.write(i);
            }
        }
        catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

කාර්යය සොකට් එකෙන් දත්ත ලබාගෙන එය තිරය මත පෙන්වයි


    private void write(InputStream sin)
    {
        try {
            int tmp;
            while (true){
                tmp = sin.read();
                System.out.print((char)tmp);
            }
        }
        catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

කාර්යය දත්ත ලබා ගැනීම සහ සම්ප්රේෂණය නතර කරයි


    public void stop()
    {
        reader.stop();
        writer.stop();
    }
}

TelnetServer

මෙම පන්තියට සොකට් එකකින් විධානයක් ලබා ගැනීම, එය ක්‍රියාත්මක කිරීම සඳහා යැවීම සහ විධානයෙන් ප්‍රතිචාරයක් නැවත සොකට් වෙත යැවීම වැනි ක්‍රියාකාරීත්වය තිබිය යුතුය. වැඩසටහන හිතාමතාම ආදාන දත්ත පරීක්ෂා නොකරයි, මන්ද පළමුව, “කොටු කළ ටෙල්නෙට්” හි පවා සේවාදායක තැටිය සංයුති කළ හැකි අතර, දෙවනුව, මෙම ලිපියේ ආරක්ෂාව පිළිබඳ ගැටළුව ප්‍රතිපත්තිමය වශයෙන් මඟ හැර ඇති අතර, එය එසේ නොවේ. සංකේතනය හෝ SSL ගැන වචනයක්.

ඇත්තේ කාර්යයන් 2 ක් පමණි (ඒවායින් එකක් අධික ලෙස පටවා ඇත), සහ පොදුවේ මෙය එතරම් හොඳ පුරුද්දක් නොවේ, නමුත් මෙම කාර්යයේ අරමුණු සඳහා, සෑම දෙයක්ම එලෙසම තැබීම සුදුසු යැයි මට පෙනුණි.

 boolean isRunning = true;
    public void run(int port)    {

        (new Thread(()->{ try {
            ServerSocket ss = new ServerSocket(port); // создаем сокет сервера и привязываем его к вышеуказанному порту
            System.out.println("Port "+port+" is waiting for connections");

            Socket socket = ss.accept();
            System.out.println("Connected");
            System.out.println();

            // Берем входной и выходной потоки сокета, теперь можем получать и отсылать данные клиенту.
            InputStream sin = socket.getInputStream();
            OutputStream sout = socket.getOutputStream();

            Map<String, String> env = System.getenv();
            String wayToTemp = env.get("TEMP") + "tmp.txt";
            for (int i :("Connectednnr".toCharArray()))
                sout.write(i);
            sout.flush();

            String buffer = new String();
            while (isRunning) {

                int intReader = 0;
                while ((char) intReader != 'n') {
                    intReader = sin.read();
                    buffer += (char) intReader;
                }


                final String inputToSubThread = "cmd /c " + buffer.substring(0, buffer.length()-2) + " 2>&1";


                new Thread(()-> {
                    try {

                        Process p = Runtime.getRuntime().exec(inputToSubThread);
                        InputStream out = p.getInputStream();
                        Scanner fromProcess = new Scanner(out);
                        try {

                            while (fromProcess.hasNextLine()) {
                                String temp = fromProcess.nextLine();
                                System.out.println(temp);
                                for (char i : temp.toCharArray())
                                    sout.write(i);
                                sout.write('n');
                                sout.write('r');
                            }
                        }
                        catch (Exception e) {
                            String output = "Something gets wrong... Err code: "+ e.getStackTrace();
                            System.out.println(output);
                            for (char i : output.toCharArray())
                                sout.write(i);
                            sout.write('n');
                            sout.write('r');
                        }

                        p.getErrorStream().close();
                        p.getOutputStream().close();
                        p.getInputStream().close();
                        sout.flush();

                    }
                    catch (Exception e) {
                        System.out.println("Error: " + e.getMessage());
                    }
                }).start();
                System.out.println(buffer);
                buffer = "";

            }
        }
        catch(Exception x) {
            System.out.println(x.getMessage());
        }})).start();

    }

වැඩසටහන සේවාදායක වරාය විවෘත කරයි, එය විධාන අවසන් අක්ෂරයක් හමු වන තුරු දත්ත කියවයි, නව ක්‍රියාවලියකට විධානය ලබා දෙයි, සහ ක්‍රියාවලියෙන් ප්‍රතිදානය සොකට් වෙත හරවා යවයි. සෑම දෙයක්ම Kalashnikov ප්රහාරක රයිෆලයක් තරම් සරල ය.

ඒ අනුව, පෙරනිමි වරායක් සමඟ මෙම කාර්යය සඳහා අධි බරක් ඇත:

 public void run()
    {
        run(23);
    }

හොඳයි, ඒ අනුව, සේවාදායකය නතර කරන කාර්යය ද සුළුපටු ය, එය සදාකාලික ලූපය බාධා කරයි, එහි තත්ත්වය උල්ලංඝනය කරයි.

    public void stop()
    {
        System.out.println("Server was stopped");
        this.isRunning = false;
    }

මම මෙහි පරීක්ෂණ පන්ති ලබා නොදෙමි, ඒවා පහත දැක්වේ - ඔවුන් කරන්නේ පොදු ක්‍රමවල ක්‍රියාකාරිත්වය පරීක්ෂා කිරීමයි. හැම දෙයක්ම git එකේ තියෙනවා.

සාරාංශගත කිරීම සඳහා, සවස් කිහිපයකදී ඔබට ප්රධාන කොන්සෝල උපයෝගීතා ක්රියාත්මක කිරීමේ මූලධර්ම තේරුම් ගත හැකිය. දැන්, අපි දුරස්ථ පරිගණකයකට ටෙලිනට් කරන විට, සිදුවන්නේ කුමක්දැයි අපට වැටහෙනවා - මැජික් අතුරුදහන් වී ඇත)

එබැවින්, සබැඳි:
සියලුම මූලාශ්‍ර මෙහි විය, පවතින සහ පවතිනු ඇත
Telnet ගැන
Telnet ගැන වැඩි විස්තර

මූලාශ්රය: www.habr.com

අදහස් එක් කරන්න