Piranti lunak nulis kanthi fungsi utilitas klien-server Windows, bagean 01

Salam.

Dina iki aku pengin ndeleng proses nulis aplikasi klien-server sing nindakake fungsi utilitas Windows standar, kayata Telnet, TFTP, lan liya-liyane, lan liya-liyane ing Jawa murni. Cetha yen aku ora bakal nggawa apa-apa sing anyar - kabeh utilitas iki wis sukses luwih saka setahun, nanging aku yakin ora kabeh wong ngerti apa sing kedadeyan ing ngisor iki.

Iki persis sing bakal dibahas ing potongan kasebut.

Ing artikel iki, supaya ora nyeret metu, saliyane kanggo informasi umum, aku mung bakal nulis bab server Telnet, nanging ing wayahe ana uga materi ing keperluan liyane - iku bakal ing bagean luwih saka seri.

Kaping pisanan, sampeyan kudu ngerti apa Telnet, apa sing dibutuhake, lan apa sing digunakake. Aku ora bakal Quote sumber verbatim (yen perlu, Aku bakal masang link kanggo bahan ing topik ing mburi artikel), Aku mung bakal ngomong sing Telnet menehi akses remot kanggo baris printah piranti. UmumΓ©, ing kene fungsine rampung (aku sengaja meneng babagan ngakses port server; luwih akeh mengko). Iki tegese kanggo ngleksanakake, kita kudu nampa baris ing klien, pass menyang server, nyoba kanggo pass menyang baris printah, maca respon baris printah, yen ana siji, pass bali menyang klien lan nampilake ing layar, utawa, yen kasalahan, supaya pangguna ngerti yen ana sing salah.

Kanggo ngleksanakake ing ndhuwur, kita butuh 2 kelas kerja lan sawetara kelas tes sing bakal diluncurake server lan klien bakal bisa digunakake.
Dadi, saiki struktur aplikasi kalebu:

  • TelnetClient
  • TelnetClientTester
  • TelnetServer
  • TelnetServerTester

Ayo padha liwat saben wong:

TelnetClient

Kabeh sing kudu ditindakake kelas iki yaiku ngirim perintah sing ditampa lan nuduhake tanggapan sing ditampa. Kajaba iku, sampeyan kudu bisa nyambung menyang port sembarang (kaya kasebut ing ndhuwur) saka piranti remot lan medhot saka iku.

Kanggo nindakake iki, fungsi ing ngisor iki ditindakake:

Fungsi sing njupuk alamat soket minangka argumen, mbukak sambungan lan miwiti input lan output stream (variabel stream diumumake ing ndhuwur, sumber lengkap ana ing pungkasan artikel).

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

Overloading fungsi sing padha, nyambung menyang port standar - kanggo telnet iki 23


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

Fungsi kasebut maca karakter saka keyboard lan dikirim menyang soket output - sing khas, ing mode baris, dudu mode karakter:


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

Fungsi kasebut nampa data saka soket lan ditampilake ing layar


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

Fungsi kasebut mandhegake panrima lan transmisi data


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

TelnetServer

Kelas iki kudu nduweni fungsi kanggo nampa printah saka soket, ngirim kanggo eksekusi, lan ngirim respon saka printah bali menyang soket. Program kasebut kanthi sengaja ora mriksa data input, amarga pisanan, sanajan ing "telnet kothak" bisa ngowahi format disk server, lan nomer loro, masalah keamanan ing artikel iki diilangi ing prinsip, lan mulane ora ana. tembung babagan enkripsi utawa SSL.

Ana mung 2 fungsi (salah siji saka wong-wong mau overloaded), lan ing umum iki ora laku apik banget, nanging kanggo tujuan tugas iki, ketoke cocok kanggo kula kanggo ninggalake kabeh minangka iku.

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

    }

Program mbukak port server, maca data saka iku nganti ketemu karakter mburi printah, liwat printah kanggo proses anyar, lan pangalihan output saka proses kanggo soket. Kabeh gampang kaya bedhil serbu Kalashnikov.

Mulane, ana kakehan kanggo fungsi iki kanthi port standar:

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

Mulane, fungsi sing mungkasi server uga ora pati penting, iku interrupts daur ulang langgeng, nglanggar kondisi sawijining.

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

Aku ora bakal menehi kelas tes ing kene, ana ing ngisor iki - kabeh sing ditindakake yaiku mriksa fungsi metode umum. Kabeh ana ing git.

Kanggo ngringkes, ing sawetara sore sampeyan bisa ngerti prinsip operasi utilitas console utama. Saiki, nalika kita telenet menyang komputer remot, kita ngerti apa sing kedadeyan - sihir wis ilang)

Dadi, pranala:
Kabeh sumber ana, saiki lan bakal ana ing kene
Babagan Telnet
Liyane babagan Telnet

Source: www.habr.com

Add a comment