ವಿಂಡೋಸ್ ಕ್ಲೈಂಟ್-ಸರ್ವರ್ ಉಪಯುಕ್ತತೆಗಳ ಕ್ರಿಯಾತ್ಮಕತೆಯೊಂದಿಗೆ ಬರೆಯುವ ಸಾಫ್ಟ್‌ವೇರ್, ಭಾಗ 01

ಶುಭಾಶಯಗಳು.

ಇಂದು ನಾನು ಕ್ಲೈಂಟ್-ಸರ್ವರ್ ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಬರೆಯುವ ಪ್ರಕ್ರಿಯೆಯನ್ನು ನೋಡಲು ಬಯಸುತ್ತೇನೆ, ಅದು ಸ್ಟ್ಯಾಂಡರ್ಡ್ ವಿಂಡೋಸ್ ಉಪಯುಕ್ತತೆಗಳ ಕಾರ್ಯಗಳನ್ನು ನಿರ್ವಹಿಸುತ್ತದೆ, ಉದಾಹರಣೆಗೆ ಟೆಲ್ನೆಟ್, ಟಿಎಫ್‌ಟಿಪಿ, ಎಟ್ ಸೆಟೆರಾ, ಇತ್ಯಾದಿ ಶುದ್ಧ ಜಾವಾದಲ್ಲಿ. ನಾನು ಹೊಸದನ್ನು ತರುವುದಿಲ್ಲ ಎಂಬುದು ಸ್ಪಷ್ಟವಾಗಿದೆ - ಈ ಎಲ್ಲಾ ಉಪಯುಕ್ತತೆಗಳು ಒಂದಕ್ಕಿಂತ ಹೆಚ್ಚು ವರ್ಷಗಳಿಂದ ಯಶಸ್ವಿಯಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತಿವೆ, ಆದರೆ ಹುಡ್ ಅಡಿಯಲ್ಲಿ ಏನಾಗುತ್ತಿದೆ ಎಂದು ಎಲ್ಲರಿಗೂ ತಿಳಿದಿಲ್ಲ ಎಂದು ನಾನು ನಂಬುತ್ತೇನೆ.

ಇದು ನಿಖರವಾಗಿ ಕಟ್ ಅಡಿಯಲ್ಲಿ ಚರ್ಚಿಸಲಾಗುವುದು.

ಈ ಲೇಖನದಲ್ಲಿ, ಅದನ್ನು ಎಳೆಯದಿರುವ ಸಲುವಾಗಿ, ಸಾಮಾನ್ಯ ಮಾಹಿತಿಯ ಜೊತೆಗೆ, ನಾನು ಟೆಲ್ನೆಟ್ ಸರ್ವರ್ ಬಗ್ಗೆ ಮಾತ್ರ ಬರೆಯುತ್ತೇನೆ, ಆದರೆ ಈ ಸಮಯದಲ್ಲಿ ಇತರ ಉಪಯುಕ್ತತೆಗಳ ಮೇಲೆ ವಸ್ತುವೂ ಇದೆ - ಇದು ಸರಣಿಯ ಮತ್ತಷ್ಟು ಭಾಗಗಳಲ್ಲಿರುತ್ತದೆ.

ಮೊದಲನೆಯದಾಗಿ, ಟೆಲ್ನೆಟ್ ಎಂದರೇನು, ಅದು ಏನು ಬೇಕು ಮತ್ತು ಅದನ್ನು ಯಾವುದಕ್ಕಾಗಿ ಬಳಸಲಾಗುತ್ತದೆ ಎಂಬುದನ್ನು ನೀವು ಕಂಡುಹಿಡಿಯಬೇಕು. ನಾನು ಮೂಲಗಳನ್ನು ಮೌಖಿಕವಾಗಿ ಉಲ್ಲೇಖಿಸುವುದಿಲ್ಲ (ಅಗತ್ಯವಿದ್ದರೆ, ಲೇಖನದ ಕೊನೆಯಲ್ಲಿ ನಾನು ವಿಷಯದ ವಿಷಯಗಳಿಗೆ ಲಿಂಕ್ ಅನ್ನು ಲಗತ್ತಿಸುತ್ತೇನೆ), ಟೆಲ್ನೆಟ್ ಸಾಧನದ ಆಜ್ಞಾ ಸಾಲಿಗೆ ರಿಮೋಟ್ ಪ್ರವೇಶವನ್ನು ಒದಗಿಸುತ್ತದೆ ಎಂದು ಮಾತ್ರ ನಾನು ಹೇಳುತ್ತೇನೆ. ದೊಡ್ಡದಾಗಿ, ಇಲ್ಲಿಯೇ ಅದರ ಕಾರ್ಯಚಟುವಟಿಕೆಯು ಕೊನೆಗೊಳ್ಳುತ್ತದೆ (ಸರ್ವರ್ ಪೋರ್ಟ್ ಅನ್ನು ಪ್ರವೇಶಿಸುವ ಬಗ್ಗೆ ನಾನು ಉದ್ದೇಶಪೂರ್ವಕವಾಗಿ ಮೌನವಾಗಿದ್ದೆ; ಅದರ ನಂತರ ಇನ್ನಷ್ಟು). ಇದರರ್ಥ ಅದನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸಲು, ನಾವು ಕ್ಲೈಂಟ್‌ನಲ್ಲಿ ಒಂದು ಸಾಲನ್ನು ಸ್ವೀಕರಿಸಬೇಕು, ಅದನ್ನು ಸರ್ವರ್‌ಗೆ ರವಾನಿಸಬೇಕು, ಅದನ್ನು ಆಜ್ಞಾ ಸಾಲಿಗೆ ರವಾನಿಸಲು ಪ್ರಯತ್ನಿಸಬೇಕು, ಆಜ್ಞಾ ಸಾಲಿನ ಪ್ರತಿಕ್ರಿಯೆಯನ್ನು ಓದಬೇಕು, ಒಂದಿದ್ದರೆ, ಅದನ್ನು ಕ್ಲೈಂಟ್‌ಗೆ ಹಿಂತಿರುಗಿಸಿ ಮತ್ತು ಅದನ್ನು ಪರದೆಯ ಮೇಲೆ ಪ್ರದರ್ಶಿಸಿ, ಅಥವಾ, ದೋಷಗಳಿದ್ದಲ್ಲಿ, ಏನೋ ತಪ್ಪಾಗಿದೆ ಎಂದು ಬಳಕೆದಾರರಿಗೆ ತಿಳಿಸಿ.

ಮೇಲಿನದನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸಲು, ಅದರ ಪ್ರಕಾರ, ನಮಗೆ 2 ಕೆಲಸದ ತರಗತಿಗಳು ಮತ್ತು ಕೆಲವು ಪರೀಕ್ಷಾ ವರ್ಗದ ಅಗತ್ಯವಿದೆ, ಇದರಿಂದ ನಾವು ಸರ್ವರ್ ಅನ್ನು ಪ್ರಾರಂಭಿಸುತ್ತೇವೆ ಮತ್ತು ಅದರ ಮೂಲಕ ಕ್ಲೈಂಟ್ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ.
ಅಂತೆಯೇ, ಈ ಸಮಯದಲ್ಲಿ ಅಪ್ಲಿಕೇಶನ್ ರಚನೆಯು ಒಳಗೊಂಡಿದೆ:

  • ಟೆಲ್ನೆಟ್ ಕ್ಲೈಂಟ್
  • TelnetClientTester
  • ಟೆಲ್ನೆಟ್ ಸರ್ವರ್
  • TelnetServerTester

ಅವುಗಳಲ್ಲಿ ಪ್ರತಿಯೊಂದರ ಮೂಲಕ ಹೋಗೋಣ:

ಟೆಲ್ನೆಟ್ ಕ್ಲೈಂಟ್

ಸ್ವೀಕರಿಸಿದ ಆಜ್ಞೆಗಳನ್ನು ಕಳುಹಿಸಲು ಮತ್ತು ಸ್ವೀಕರಿಸಿದ ಪ್ರತಿಕ್ರಿಯೆಗಳನ್ನು ತೋರಿಸಲು ಈ ವರ್ಗವು ಮಾಡಲು ಸಾಧ್ಯವಾಗುತ್ತದೆ. ಹೆಚ್ಚುವರಿಯಾಗಿ, ನೀವು ದೂರಸ್ಥ ಸಾಧನದ ಅನಿಯಂತ್ರಿತ (ಮೇಲೆ ತಿಳಿಸಿದಂತೆ) ಪೋರ್ಟ್‌ಗೆ ಸಂಪರ್ಕಿಸಲು ಸಾಧ್ಯವಾಗುತ್ತದೆ ಮತ್ತು ಅದರಿಂದ ಸಂಪರ್ಕ ಕಡಿತಗೊಳಿಸಬೇಕು.

ಇದನ್ನು ಸಾಧಿಸಲು, ಈ ಕೆಳಗಿನ ಕಾರ್ಯಗಳನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸಲಾಗಿದೆ:

ಸಾಕೆಟ್ ವಿಳಾಸವನ್ನು ವಾದವಾಗಿ ತೆಗೆದುಕೊಳ್ಳುವ ಕಾರ್ಯ, ಸಂಪರ್ಕವನ್ನು ತೆರೆಯುತ್ತದೆ ಮತ್ತು ಇನ್‌ಪುಟ್ ಮತ್ತು ಔಟ್‌ಪುಟ್ ಸ್ಟ್ರೀಮ್‌ಗಳನ್ನು ಪ್ರಾರಂಭಿಸುತ್ತದೆ (ಸ್ಟ್ರೀಮ್ ವೇರಿಯಬಲ್‌ಗಳನ್ನು ಮೇಲೆ ಘೋಷಿಸಲಾಗಿದೆ, ಪೂರ್ಣ ಮೂಲಗಳು ಲೇಖನದ ಕೊನೆಯಲ್ಲಿವೆ).

 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();
    }
}

ಟೆಲ್ನೆಟ್ ಸರ್ವರ್

ಈ ವರ್ಗವು ಸಾಕೆಟ್‌ನಿಂದ ಆಜ್ಞೆಯನ್ನು ಸ್ವೀಕರಿಸುವ ಕಾರ್ಯವನ್ನು ಹೊಂದಿರಬೇಕು, ಅದನ್ನು ಮರಣದಂಡನೆಗೆ ಕಳುಹಿಸುವುದು ಮತ್ತು ಆಜ್ಞೆಯಿಂದ ಪ್ರತಿಕ್ರಿಯೆಯನ್ನು ಸಾಕೆಟ್‌ಗೆ ಕಳುಹಿಸುವುದು. ಪ್ರೋಗ್ರಾಂ ಉದ್ದೇಶಪೂರ್ವಕವಾಗಿ ಇನ್ಪುಟ್ ಡೇಟಾವನ್ನು ಪರಿಶೀಲಿಸುವುದಿಲ್ಲ, ಏಕೆಂದರೆ ಮೊದಲನೆಯದಾಗಿ, "ಬಾಕ್ಸ್ಡ್ ಟೆಲ್ನೆಟ್" ನಲ್ಲಿಯೂ ಸಹ ಸರ್ವರ್ ಡಿಸ್ಕ್ ಅನ್ನು ಫಾರ್ಮ್ಯಾಟ್ ಮಾಡಲು ಸಾಧ್ಯವಿದೆ, ಮತ್ತು ಎರಡನೆಯದಾಗಿ, ಈ ಲೇಖನದಲ್ಲಿನ ಭದ್ರತೆಯ ಸಮಸ್ಯೆಯನ್ನು ತಾತ್ವಿಕವಾಗಿ ಬಿಟ್ಟುಬಿಡಲಾಗಿದೆ ಮತ್ತು ಅದಕ್ಕಾಗಿಯೇ ಇಲ್ಲ ಗೂಢಲಿಪೀಕರಣ ಅಥವಾ 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();

    }

ಪ್ರೋಗ್ರಾಂ ಸರ್ವರ್ ಪೋರ್ಟ್ ಅನ್ನು ತೆರೆಯುತ್ತದೆ, ಕಮಾಂಡ್ ಎಂಡ್ ಕ್ಯಾರೆಕ್ಟರ್ ಅನ್ನು ಎದುರಿಸುವವರೆಗೆ ಅದರಿಂದ ಡೇಟಾವನ್ನು ಓದುತ್ತದೆ, ಹೊಸ ಪ್ರಕ್ರಿಯೆಗೆ ಆಜ್ಞೆಯನ್ನು ರವಾನಿಸುತ್ತದೆ ಮತ್ತು ಪ್ರಕ್ರಿಯೆಯಿಂದ ಸಾಕೆಟ್‌ಗೆ ಔಟ್‌ಪುಟ್ ಅನ್ನು ಮರುನಿರ್ದೇಶಿಸುತ್ತದೆ. ಎಲ್ಲವೂ ಕಲಾಶ್ನಿಕೋವ್ ಆಕ್ರಮಣಕಾರಿ ರೈಫಲ್‌ನಂತೆ ಸರಳವಾಗಿದೆ.

ಅಂತೆಯೇ, ಡೀಫಾಲ್ಟ್ ಪೋರ್ಟ್‌ನೊಂದಿಗೆ ಈ ಕಾರ್ಯಕ್ಕಾಗಿ ಓವರ್‌ಲೋಡ್ ಇದೆ:

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

ಸರಿ, ಅದರ ಪ್ರಕಾರ, ಸರ್ವರ್ ಅನ್ನು ನಿಲ್ಲಿಸುವ ಕಾರ್ಯವು ಸಹ ಕ್ಷುಲ್ಲಕವಾಗಿದೆ, ಇದು ಶಾಶ್ವತ ಲೂಪ್ ಅನ್ನು ಅಡ್ಡಿಪಡಿಸುತ್ತದೆ, ಅದರ ಸ್ಥಿತಿಯನ್ನು ಉಲ್ಲಂಘಿಸುತ್ತದೆ.

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

ನಾನು ಇಲ್ಲಿ ಪರೀಕ್ಷಾ ತರಗತಿಗಳನ್ನು ನೀಡುವುದಿಲ್ಲ, ಅವುಗಳು ಕೆಳಗಿವೆ - ಸಾರ್ವಜನಿಕ ವಿಧಾನಗಳ ಕಾರ್ಯವನ್ನು ಪರಿಶೀಲಿಸುವುದು ಮಾತ್ರ. ಎಲ್ಲವೂ ಜಿಟ್‌ನಲ್ಲಿದೆ.

ಸಂಕ್ಷಿಪ್ತವಾಗಿ ಹೇಳುವುದಾದರೆ, ಒಂದೆರಡು ಸಂಜೆಗಳಲ್ಲಿ ನೀವು ಮುಖ್ಯ ಕನ್ಸೋಲ್ ಉಪಯುಕ್ತತೆಗಳ ಕಾರ್ಯಾಚರಣೆಯ ತತ್ವಗಳನ್ನು ಅರ್ಥಮಾಡಿಕೊಳ್ಳಬಹುದು. ಈಗ, ನಾವು ರಿಮೋಟ್ ಕಂಪ್ಯೂಟರ್‌ಗೆ ಟೆಲಿನೆಟ್ ಮಾಡಿದಾಗ, ಏನಾಗುತ್ತಿದೆ ಎಂದು ನಾವು ಅರ್ಥಮಾಡಿಕೊಳ್ಳುತ್ತೇವೆ - ಮ್ಯಾಜಿಕ್ ಕಣ್ಮರೆಯಾಯಿತು)

ಆದ್ದರಿಂದ, ಲಿಂಕ್‌ಗಳು:
ಎಲ್ಲಾ ಮೂಲಗಳು ಇದ್ದವು, ಇವೆ ಮತ್ತು ಇಲ್ಲಿರುತ್ತದೆ
ಟೆಲ್ನೆಟ್ ಬಗ್ಗೆ
ಟೆಲ್ನೆಟ್ ಬಗ್ಗೆ ಇನ್ನಷ್ಟು

ಮೂಲ: www.habr.com

ಕಾಮೆಂಟ್ ಅನ್ನು ಸೇರಿಸಿ