Kitba ta 'softwer bil-funzjonalità tal-utilitajiet Windows client-server, parti 01

Awguri.

Illum nixtieq inħares lejn il-proċess tal-kitba ta 'applikazzjonijiet klijent-server li jwettqu l-funzjonijiet ta' utilitajiet standard tal-Windows, bħal Telnet, TFTP, eċċetera, eċċetera f'Java pur. Huwa ċar li mhux se nġib xejn ġdid - dawn l-utilitajiet kollha ilhom jaħdmu b'suċċess għal aktar minn sena, iżda nemmen li mhux kulħadd jaf x'inhu għaddej taħt il-barnuża.

Dan huwa eżattament dak li se jiġi diskuss taħt il-qatgħa.

F'dan l-artikolu, sabiex ma nkaxkrux, minbarra l-informazzjoni ġenerali, se nikteb biss dwar is-server Telnet, iżda bħalissa hemm ukoll materjal dwar utilitajiet oħra - se jkun f'partijiet ulterjuri tas-serje.

L-ewwelnett, trid tifhem x'inhu Telnet, għalxiex huwa meħtieġ, u għalxiex jintuża. Mhux se nikkwota sorsi verbatim (jekk meħtieġ, se nehmeż link għal materjali dwar is-suġġett fl-aħħar tal-artiklu), se ngħid biss li Telnet jipprovdi aċċess remot għal-linja tal-kmand tal-apparat. B'mod ġenerali, dan huwa fejn tispiċċa l-funzjonalità tagħha (I deliberatament żammejt siekta dwar l-aċċess għall-port tas-server; aktar dwar dan aktar tard). Dan ifisser li biex nimplimentah, għandna bżonn naċċettaw linja fuq il-klijent, ngħadduha lis-server, nippruvaw ngħadduha lil-linja tal-kmand, aqra r-rispons tal-linja tal-kmand, jekk hemm waħda, tgħaddiha lura lill-klijent u juriha fuq l-iskrin, jew, jekk ikun hemm żbalji, ħalli l-utent ikun jaf li xi ħaġa hija ħażina.

Biex nimplimentaw dan ta 'hawn fuq, għalhekk, għandna bżonn 2 klassijiet tax-xogħol u xi klassi tat-test li minnha se nniedu s-server u li permezz tagħhom il-klijent se jaħdem.
Għaldaqstant, bħalissa l-istruttura tal-applikazzjoni tinkludi:

  • TelnetClient
  • TelnetClientTester
  • TelnetServer
  • TelnetServerTester

Ejja ngħaddu minn kull wieħed minnhom:

TelnetClient

Din il-klassi kollha għandha tkun kapaċi tagħmel hu li tibgħat kmandi riċevuti u turi r-risposti riċevuti. Barra minn hekk, jeħtieġ li tkun tista 'tqabbad ma' port arbitrarju (kif imsemmi hawn fuq) ta 'apparat remot u skonnettja minnu.

Biex jinkiseb dan, ġew implimentati l-funzjonijiet li ġejjin:

Funzjoni li tieħu indirizz tas-socket bħala argument, tiftaħ konnessjoni u tibda flussi ta 'input u output (il-varjabbli tan-nixxiegħa huma ddikjarati hawn fuq, is-sorsi sħaħ huma fl-aħħar tal-artiklu).

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

Tagħbija żejda tal-istess funzjoni, konnessjoni mal-port default - għal telnet dan huwa 23


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

Il-funzjoni taqra karattri mit-tastiera u tibgħathom lis-socket tal-output - li huwa tipiku, fil-modalità tal-linja, mhux il-mod tal-karattri:


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

Il-funzjoni tirċievi data mis-sokit u turiha fuq l-iskrin


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

Il-funzjoni twaqqaf ir-riċeviment u t-trażmissjoni tad-data


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

TelnetServer

Din il-klassi għandu jkollha l-funzjonalità li tirċievi kmand minn socket, tibgħatha għall-eżekuzzjoni, u tibgħat tweġiba mill-kmand lura lis-socket. Il-programm deliberatament ma jiċċekkjax id-dejta tal-input, għaliex l-ewwelnett, anki f'"telnet boxed" huwa possibbli li d-diska tas-server tiġi fformattjata, u t-tieni, il-kwistjoni tas-sigurtà f'dan l-artikolu titħalla barra fil-prinċipju, u huwa għalhekk li m'hemmx kelma dwar encryption jew SSL.

Hemm 2 funzjonijiet biss (waħda minnhom hija mgħobbija żżejjed), u b'mod ġenerali din mhix prattika tajba ħafna, iżda għall-finijiet ta 'dan il-kompitu, deherli xieraq li nħalli kollox kif inhu.

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

    }

Il-programm jiftaħ il-port tas-server, jaqra d-dejta minnu sakemm jiltaqa 'ma' karattru tat-tmiem tal-kmand, jgħaddi l-kmand għal proċess ġdid, u jidderieġi mill-ġdid l-output mill-proċess għas-sokit. Kollox huwa sempliċi daqs xkubetta tal-attakk Kalashnikov.

Għaldaqstant, hemm tagħbija żejda għal din il-funzjoni b'port default:

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

Ukoll, għalhekk, il-funzjoni li twaqqaf is-server hija wkoll trivjali, tinterrompi l-linja eterna, u tikser il-kundizzjoni tagħha.

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

Mhux se nagħti klassijiet tat-test hawn, huma hawn taħt - kull ma jagħmlu hu li jiċċekkjaw il-funzjonalità tal-metodi pubbliċi. Kollox jinsab fuq il-git.

Fil-qosor, fi ftit filgħaxija tista 'tifhem il-prinċipji ta' tħaddim tal-utilitajiet prinċipali tal-console. Issa, meta aħna telenet għal kompjuter remot, nifhmu x'qed jiġri - il-maġija sparixxa)

Allura, il-links:
Is-sorsi kollha kienu, huma u se jkunu hawn
Dwar Telnet
Aktar dwar Telnet

Sors: www.habr.com

Żid kumment