Meddalwedd ysgrifennu gyda swyddogaeth cyfleustodau gweinydd cleient Windows, rhan 01

Cyfarchion.

Heddiw hoffwn edrych ar y broses o ysgrifennu cymwysiadau cleient-gweinydd sy'n cyflawni swyddogaethau cyfleustodau safonol Windows, megis Telnet, TFTP, et cetera, et cetera mewn Java pur. Mae'n amlwg na fyddaf yn dod Γ’ dim byd newydd - mae'r holl gyfleustodau hyn wedi bod yn gweithio'n llwyddiannus ers mwy na blwyddyn, ond credaf nad yw pawb yn gwybod beth sy'n digwydd o dan y cwfl.

Dyma’n union fydd yn cael ei drafod o dan y toriad.

Yn yr erthygl hon, er mwyn peidio Γ’'i lusgo allan, yn ogystal Γ’ gwybodaeth gyffredinol, dim ond am y gweinydd Telnet y byddaf yn ysgrifennu, ond ar hyn o bryd mae yna hefyd ddeunydd ar gyfleustodau eraill - bydd mewn rhannau pellach o'r gyfres.

Yn gyntaf oll, mae angen i chi ddarganfod beth yw Telnet, beth sydd ei angen ar ei gyfer, ac ar gyfer beth mae'n cael ei ddefnyddio. Ni fyddaf yn dyfynnu ffynonellau gair am air (os oes angen, byddaf yn atodi dolen i ddeunyddiau ar y pwnc ar ddiwedd yr erthygl), ni fyddaf ond yn dweud bod Telnet yn darparu mynediad anghysbell i linell orchymyn y ddyfais. Ar y cyfan, dyma lle mae ei ymarferoldeb yn dod i ben (fe wnes i gadw'n dawel yn fwriadol ynglΕ·n Γ’ chyrchu porthladd y gweinydd; mwy am hynny yn nes ymlaen). Mae hyn yn golygu, er mwyn ei weithredu, bod angen i ni dderbyn llinell ar y cleient, ei throsglwyddo i'r gweinydd, ceisio ei throsglwyddo i'r llinell orchymyn, darllenwch ymateb y llinell orchymyn, os oes un, ei throsglwyddo yn Γ΄l i'r cleient a ei arddangos ar y sgrin, neu, os oes gwallau, rhowch wybod i'r defnyddiwr bod rhywbeth o'i le.

I weithredu'r uchod, yn unol Γ’ hynny, mae angen 2 ddosbarth gwaith a rhywfaint o ddosbarth prawf y byddwn yn lansio'r gweinydd ohono a bydd y cleient yn gweithio drwyddo.
Yn unol Γ’ hynny, ar hyn o bryd mae strwythur y cais yn cynnwys:

  • TelnetClient
  • TelnetClientTester
  • TelnetServer
  • TelnetServerTester

Gadewch i ni fynd trwy bob un ohonynt:

TelnetClient

Y cyfan y dylai'r dosbarth hwn allu ei wneud yw anfon gorchmynion a dderbyniwyd a dangos yr ymatebion a dderbyniwyd. Yn ogystal, mae angen i chi allu cysylltu Γ’ phorthladd mympwyol (fel y soniwyd uchod) o ddyfais bell a datgysylltu oddi wrtho.

I gyflawni hyn, gweithredwyd y swyddogaethau canlynol:

Swyddogaeth sy'n cymryd cyfeiriad soced fel dadl, yn agor cysylltiad ac yn cychwyn ffrydiau mewnbwn ac allbwn (mae newidynnau ffrwd wedi'u datgan uchod, mae ffynonellau llawn ar ddiwedd yr erthygl).

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

Gorlwytho'r un swyddogaeth, cysylltu Γ’'r porthladd rhagosodedig - 23 yw hwn ar gyfer telnet


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

Mae'r ffwythiant yn darllen nodau o'r bysellfwrdd ac yn eu hanfon i'r soced allbwn - sy'n nodweddiadol, yn y modd llinell, nid y modd nod:


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

Mae'r swyddogaeth yn derbyn data o'r soced ac yn ei arddangos ar y sgrin


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

Mae'r swyddogaeth yn atal derbyn a throsglwyddo data


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

TelnetServer

Rhaid i'r dosbarth hwn fod Γ’'r swyddogaeth o dderbyn gorchymyn o soced, ei anfon i'w weithredu, ac anfon ymateb o'r gorchymyn yn Γ΄l i'r soced. Nid yw'r rhaglen yn gwirio'r data mewnbwn yn fwriadol, oherwydd yn gyntaf, hyd yn oed yn "telnet bocsys" mae'n bosibl fformatio disg y gweinydd, ac yn ail, mae mater diogelwch yn yr erthygl hon yn cael ei hepgor mewn egwyddor, a dyna pam nad oes gair am amgryptio neu SSL.

Dim ond 2 swyddogaeth sydd (mae un ohonynt wedi'i orlwytho), ac yn gyffredinol nid yw hyn yn arfer da iawn, ond at ddibenion y dasg hon, roedd yn ymddangos yn briodol i mi adael popeth fel y mae.

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

    }

Mae'r rhaglen yn agor porthladd y gweinydd, yn darllen data ohono nes ei fod yn dod ar draws nod diwedd gorchymyn, yn trosglwyddo'r gorchymyn i broses newydd, ac yn ailgyfeirio'r allbwn o'r broses i'r soced. Mae popeth mor syml Γ’ reiffl ymosod Kalashnikov.

Yn unol Γ’ hynny, mae gorlwytho ar gyfer y swyddogaeth hon gyda phorthladd rhagosodedig:

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

Wel, yn unol Γ’ hynny, mae'r swyddogaeth sy'n atal y gweinydd hefyd yn ddibwys, mae'n torri ar draws y ddolen dragwyddol, gan dorri ei gyflwr.

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

Ni fyddaf yn rhoi dosbarthiadau prawf yma, maen nhw isod - y cyfan maen nhw'n ei wneud yw gwirio ymarferoldeb dulliau cyhoeddus. Mae popeth ar y git.

I grynhoi, mewn cwpl o nosweithiau gallwch chi ddeall egwyddorion gweithredu'r prif gyfleustodau consol. Nawr, pan rydyn ni'n telenet i gyfrifiadur anghysbell, rydyn ni'n deall beth sy'n digwydd - mae'r hud wedi diflannu)

Felly, y dolenni:
Roedd yr holl ffynonellau yma, sydd ac y byddant yma
Am Telnet
Mwy am Telnet

Ffynhonnell: hab.com

Ychwanegu sylw