Pagsulat sa software nga adunay gamit sa Windows client-server utilities, bahin 01

Mga pangomosta.

Karon gusto nakong tan-awon ang proseso sa pagsulat sa mga aplikasyon sa client-server nga naghimo sa mga gimbuhaton sa standard Windows utilities, sama sa Telnet, TFTP, et cetera, et cetera sa pure Java. Klaro nga dili ako magdala bisan unsa nga bag-o - kining tanan nga mga utilities malampuson nga nagtrabaho sa sobra sa usa ka tuig, apan nagtuo ako nga dili tanan nahibal-an kung unsa ang nahitabo sa ilawom sa hood.

Mao gyud kini ang hisgutan ubos sa pagputol.

Niini nga artikulo, aron dili kini ma-drag, dugang sa kinatibuk-ang impormasyon, magsulat lamang ako mahitungod sa Telnet server, apan sa pagkakaron adunay materyal usab sa ubang mga utilities - kini anaa sa dugang nga mga bahin sa serye.

Una sa tanan, kinahanglan nimo nga mahibal-an kung unsa ang Telnet, kung unsa ang kinahanglan niini, ug kung unsa kini gigamit. Dili ko mokutlo sa mga tinubdan verbatim (kon gikinahanglan, ako maglakip sa usa ka link sa mga materyales sa hilisgutan sa katapusan sa artikulo), ako lamang moingon nga ang Telnet naghatag og hilit nga access sa command line sa device. Sa kadaghanon, dinhi natapos ang pag-andar niini (tinuyo ko nga nagpakahilom bahin sa pag-access sa pantalan sa server; labi pa sa ulahi). Kini nagpasabot nga aron ipatuman kini, kinahanglan natong dawaton ang usa ka linya sa kliyente, ipasa kini sa server, sulayi nga ipasa kini sa command line, basaha ang tubag sa command line, kung adunay usa, ipasa kini balik sa kliyente ug ipakita kini sa screen, o, kung adunay mga sayup, ipahibalo sa tiggamit nga adunay sayup.

Aron ipatuman ang naa sa ibabaw, sumala niana, kinahanglan namon ang 2 nga mga klase sa pagtrabaho ug pipila nga klase sa pagsulay diin among ilunsad ang server ug diin ang kliyente molihok.
Tungod niini, sa pagkakaron ang istruktura sa aplikasyon naglakip sa:

  • TelnetClient
  • TelnetClientTester
  • TelnetServer
  • TelnetServerTester

Atong susihon ang matag usa kanila:

TelnetClient

Ang tanan nga mahimo niini nga klase mao ang pagpadala sa nadawat nga mga mando ug ipakita ang nadawat nga mga tubag. Dugang pa, kinahanglan nimo nga makakonektar sa usa ka arbitraryo (sama sa gihisgutan sa ibabaw) nga pantalan sa usa ka hilit nga aparato ug idiskonekta gikan niini.

Aron makab-ot kini, ang mosunod nga mga gimbuhaton gipatuman:

Usa ka function nga nagkuha sa usa ka socket address ingon usa ka argumento, nagbukas sa usa ka koneksyon ug nagsugod sa input ug output nga mga sapa (ang mga variable sa sapa gipahayag sa ibabaw, ang tibuuk nga gigikanan naa sa katapusan sa artikulo).

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

Pag-overload sa parehas nga function, pagkonektar sa default port - alang sa telnet kini 23


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

Ang function nagbasa sa mga karakter gikan sa keyboard ug gipadala kini sa output socket - nga kasagaran, sa line mode, dili character mode:


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

Ang function nakadawat data gikan sa socket ug gipakita kini sa screen


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

Ang function nagpahunong sa pagdawat ug pagpadala sa datos


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

TelnetServer

Kini nga klase kinahanglan nga adunay function sa pagdawat sa usa ka mando gikan sa usa ka socket, ipadala kini aron ipatuman, ug ipadala ang tubag gikan sa mando balik sa socket. Ang programa tinuyo nga wala magsusi sa input data, tungod kay una, bisan sa "boxed telnet" posible nga ma-format ang server disk, ug ikaduha, ang isyu sa seguridad niini nga artikulo wala iapil sa prinsipyo, ug mao nga wala'y usa ka pulong mahitungod sa encryption o SSL.

Adunay 2 ra nga mga gimbuhaton (usa niini ang sobra nga gibug-aton), ug sa kinatibuk-an kini dili kaayo maayo nga praktis, apan alang sa mga katuyoan niini nga buluhaton, ingon og angay kanako nga biyaan ang tanan nga ingon niini.

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

    }

Giablihan sa programa ang port sa server, gibasa ang datos gikan niini hangtod nga makit-an ang usa ka karakter sa katapusan sa mando, gipasa ang mando sa usa ka bag-ong proseso, ug gi-redirect ang output gikan sa proseso ngadto sa socket. Ang tanan yano ra sama sa usa ka Kalashnikov assault rifle.

Tungod niini, adunay sobra nga gibug-aton alang niini nga function nga adunay default nga pantalan:

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

Aw, sumala niana, ang function nga nagpahunong sa server gamay ra usab, kini nakabalda sa walay katapusan nga loop, naglapas sa kahimtang niini.

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

Dili ko maghatag mga klase sa pagsulay dinhi, naa sila sa ubos - ang ilang gibuhat mao ang pagsusi sa pagpaandar sa mga pamaagi sa publiko. Ang tanan naa sa git.

Sa pag-summarize, sa usa ka magtiayon nga sa mga gabii imong masabtan ang mga prinsipyo sa operasyon sa mga nag-unang console utilities. Karon, kung nag-telenet kami sa usa ka hilit nga kompyuter, nahibal-an namon kung unsa ang nahitabo - nawala ang salamangka)

Busa, ang mga link:
Ang tanan nga mga tinubdan kaniadto, anaa ug ania dinhi
Mahitungod sa Telnet
Dugang pa bahin sa Telnet

Source: www.habr.com

Idugang sa usa ka comment