Bogearraí scríbhneoireachta le feidhmiúlacht fóntais cliant-freastalaí Windows, cuid 02

Ag leanúint leis an tsraith leanúnach d'alt atá dírithe ar fheidhmiú saincheaptha fóntais chonsóil Windows, ní féidir linn cabhrú ach teagmháil a dhéanamh le TFTP (Prótacal Aistrithe Comhad Fánach) - prótacal aistrithe comhad simplí.

Mar an uair dheireanach, déanaimis dul go hachomair ar an teoiric, féach ar an gcód a chuireann feidhmiúlacht i bhfeidhm cosúil leis an gceann atá ag teastáil, agus déan anailís air. Tuilleadh sonraí - faoin gearrtha

Ní dhéanfaidh mé cóipeáil-greamaigh faisnéis tagartha, naisc is féidir a fháil go traidisiúnta ag deireadh an ailt, beidh mé a rá go díreach go bhfuil ag a chroí, TFTP athrú simplithe ar an prótacal FTP, ina bhfuil an socrú rialaithe rochtana bainte, agus i ndáiríre níl aon rud anseo ach amháin orduithe chun comhad a fháil agus a aistriú . Mar sin féin, chun ár gcur chun feidhme a dhéanamh beagán níos galánta agus oiriúnaithe do na prionsabail atá ann faoi láthair maidir le cód scríbhneoireachta, tá an chomhréir athraithe beagán - ní athraíonn sé seo prionsabail na hoibríochta, ach éiríonn an comhéadan, IMHO, beagán níos loighciúil agus comhcheanglaíonn sé gnéithe dearfacha FTP agus TFTP.

Go háirithe, nuair a seoladh é, iarrann an cliant seoladh IP an fhreastalaí agus an calafort ar a bhfuil TFTP saincheaptha oscailte (mar gheall ar neamh-chomhoiriúnacht leis an bprótacal caighdeánach, mheas mé go raibh sé oiriúnach an cumas port a roghnú don úsáideoir), agus ina dhiaidh sin a nasc a tharlaíonn, mar thoradh ar féidir leis an gcliant a sheoladh ar cheann de na horduithe - a fháil nó a chur, a fháil nó a sheoladh comhad chuig an bhfreastalaí. Seoltar gach comhad i mód dénártha chun an loighic a shimpliú.

Chun an prótacal a chur i bhfeidhm, bhain mé úsáid as 4 rang go traidisiúnta:

  • TFTTPClient
  • Freastalaí TFTPS
  • TTFTPClientTester
  • Tástálaí Freastalaí TFTP

Toisc nach bhfuil ranganna tástála ann ach chun na príomhchinn a dhífhabhtú, ní dhéanfaidh mé anailís orthu, ach beidh an cód sa stór; tá nasc chuige le fáil ag deireadh an ailt. Anois breathnóidh mé ar na príomh ranganna.

TFTTPClient

Is é tasc an aicme seo ná ceangal le cianfhreastalaí ag baint úsáide as a ip agus uimhir phoirt, ordú a léamh ón sruth ionchuir (sa chás seo, an méarchlár), é a pharsáil, é a aistriú chuig an bhfreastalaí, agus, ag brath ar cé acu an bhfuil tú gá comhad a sheoladh nó a fháil, é a aistriú nó a fháil.

Breathnaíonn an cód chun an cliant a sheoladh chun ceangal leis an bhfreastalaí agus fanacht ar ordú ón sruth ionchuir mar seo. Déantar cur síos ar roinnt athróg dhomhanda a úsáidtear anseo lasmuigh den alt, i dtéacs iomlán an chláir. Mar gheall ar a gcuid fánach, ní luann mé iad ionas nach gcuirfí ró-ualach ar an alt.

 public void run(String ip, int port)
    {
        this.ip = ip;
        this.port = port;
        try {
            inicialization();
            Scanner keyboard = new Scanner(System.in);
            while (isRunning) {
                getAndParseInput(keyboard);
                sendCommand();
                selector();
                }
            }
        catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

Rachaimid thar na modhanna ar a dtugtar sa bhloc cód seo:

Anseo seoltar an comhad - ag baint úsáide as scanóir, cuirimid ábhar an chomhaid i láthair mar shraith beart, a scríobhaimid ceann ar cheann chuig an soicéad, agus ina dhiaidh sin dúnann muid é agus osclaítear arís é (ní hé an réiteach is soiléire, ach ráthaíonn sé go scaoilfear acmhainní), agus ina dhiaidh sin taispeánaimid teachtaireacht faoi aistriú rathúil.

private  void put(String sourcePath, String destPath)
    {

        File src = new File(sourcePath);
        try {

            InputStream scanner = new FileInputStream(src);
            byte[] bytes = scanner.readAllBytes();
            for (byte b : bytes)
                sout.write(b);
            sout.close();
            inicialization();
            System.out.println("nDonen");
            }

        catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

Déanann an blúire cód seo cur síos ar aisghabháil sonraí ón bhfreastalaí. Tá gach rud fánach arís, níl ach an chéad bhloc cód spéise. Chun a thuiscint go díreach cé mhéad beart is gá a léamh as an soicéad, ní mór duit fios a bheith agat cé mhéad meáchan atá sa chomhad aistrithe. Léirítear méid an chomhaid ar an bhfreastalaí mar shlánuimhir fhada, agus mar sin glactar le 4 beart anseo, a thiontaítear ina uimhir amháin ina dhiaidh sin. Ní cur chuige an-Java é seo, tá sé sách cosúil le SI, ach réitíonn sé a fhadhb.

Ansin tá gach rud fánach - faigheann muid líon aitheanta beart ón soicéad agus scríobhtar chuig comhad iad, agus ina dhiaidh sin taispeánaimid teachtaireacht ratha.

   private void get(String sourcePath, String destPath){
        long sizeOfFile = 0;
        try {


            byte[] sizeBytes = new byte[Long.SIZE];
           for (int i =0; i< Long.SIZE/Byte.SIZE; i++)
           {
               sizeBytes[i] = (byte)sin.read();
               sizeOfFile*=256;
               sizeOfFile+=sizeBytes[i];
           }

           FileOutputStream writer = new FileOutputStream(new File(destPath));
           for (int i =0; i < sizeOfFile; i++)
           {
               writer.write(sin.read());
           }
           writer.close();
           System.out.println("nDONEn");
       }
       catch (Exception e){
            System.out.println(e.getMessage());
       }
    }

Má cuireadh ordú seachas fáil nó cur isteach i bhfuinneog an chliaint, glaofar an fheidhm showErrorMessage, rud a thugann le fios go raibh an t-ionchur mícheart. Mar gheall ar fánach, ní luafaidh mé é. Rud níos suimiúla ná an fheidhm a bhaineann leis an sreang ionchuir a fháil agus a scoilteadh. Gabhaimid an scanóir isteach ann, as a mbeimid ag súil le líne a fháil atá scartha le dhá spás agus ina mbeidh an t-ordú, an seoladh foinse agus an seoladh ceann scríbe.

    private void getAndParseInput(Scanner scanner)
    {
        try {

            input = scanner.nextLine().split(" ");
            typeOfCommand = input[0];
            sourcePath = input[1];
            destPath = input[2];
        }
        catch (Exception e) {
            System.out.println("Bad input");
        }
    }

Ordú a sheoladh - seolann sé an t-ordú a iontráladh ón scanóir go dtí an soicéad agus cuireann sé iallach é a sheoladh

    private void sendCommand()
    {
        try {

            for (String str : input) {
                for (char ch : str.toCharArray()) {
                    sout.write(ch);
                }
                sout.write(' ');
            }
            sout.write('n');
        }
        catch (Exception e) {
            System.out.print(e.getMessage());
        }
    }

Is feidhm é roghnóir a chinneann gníomhartha an chláir ag brath ar an teaghrán iontrála. Níl gach rud anseo an-álainn agus ní hé an cleas a úsáidtear an ceann is fearr le himeacht éigean lasmuigh den bhloc cóid, ach is é an príomhchúis atá leis seo ná nach bhfuil roinnt rudaí i Java, mar shampla na toscairí in C#, leideanna feidhme ó C++, nó ag ar a laghad an goto uafásach agus uafásach, a ligeann duit é seo a chur i bhfeidhm go hálainn. Má tá a fhios agat conas an cód a dhéanamh beagán níos galánta, cuirim fáilte roimh cáineadh sna tuairimí. Feictear domsa go bhfuil gá le foclóir teaghrán toscairí anseo, ach níl aon toscaire...

    private void selector()
    {
        do{
            if (typeOfCommand.equals("get")){
                get(sourcePath, destPath);
                break;
            }
            if (typeOfCommand.equals("put")){
                put(sourcePath, destPath);
                break;
            }
            showErrorMessage();
        }
        while (false);
    }
}

Freastalaí TFTPS

Ní hionann feidhmiúlacht an fhreastalaí agus feidhmiúlacht an chliaint, den chuid is mó, ach amháin sa mhéid is go dtagann orduithe chuige ní ón méarchlár, ach ón soicéad. Tá cuid de na modhanna mar an gcéanna go ginearálta, mar sin ní luafaidh mé iad, ní dhéanfaidh mé teagmháil ach ar na difríochtaí.

Chun tús a chur leis, úsáidtear an modh reáchtáil, a fhaigheann port mar ionchur agus a phróiseálann na sonraí ionchuir ón soicéad i lúb síoraí.

    public void run(int port) {
            this.port = port;
            incialization();
            while (true) {
                getAndParseInput();
                selector();
            }
    }

Taispeánann an modh cuir, a chumhdaíonn an modh writeToFileFromSocket a osclaíonn sruth scríobh chuig comhad agus a scríobhann gach beart ionchuir ón soicéad, teachtaireacht a thugann le fios gur éirigh leis an aistriú nuair a chríochnaíonn an scríobh.

    private  void put(String source, String dest){
            writeToFileFromSocket();
            System.out.print("nDonen");
    };
    private void writeToFileFromSocket()
    {
        try {
            FileOutputStream writer = new FileOutputStream(new File(destPath));
            byte[] bytes = sin.readAllBytes();
            for (byte b : bytes) {
                writer.write(b);
            }
            writer.close();
        }
        catch (Exception e){
            System.out.println(e.getMessage());
        }
    }

Aisghabhann an modh faigh an comhad freastalaí. Mar a luadh cheana sa chuid ar thaobh an chliaint den chlár, chun comhad a aistriú go rathúil ní mór duit fios a bheith agat ar a mhéid, a stóráiltear i slánuimhir fhada, agus mar sin scoilt mé é i sraith de 4 bytes, aistrigh iad beart-by-byte. chuig an soicéad, agus ansin, tar éis iad a fháil agus a chur le chéile ar an gcliant isteach i uimhir ar ais, aistrím na bearta go léir a dhéanann suas an comhad, a léamh ón sruth ionchuir ón gcomhad.


 private  void get(String source, String dest){
        File sending = new File(source);
        try {
            FileInputStream readFromFile = new FileInputStream(sending);
            byte[] arr = readFromFile.readAllBytes();
            byte[] bytes = ByteBuffer.allocate(Long.SIZE / Byte.SIZE).putLong(sending.length()).array();
            for (int i = 0; i<Long.SIZE / Byte.SIZE; i++)
                sout.write(bytes[i]);
            sout.flush();
            for (byte b : arr)
                sout.write(b);
        }
        catch (Exception e){
            System.out.println(e.getMessage());
        }
    };

Tá an modh getAndParseInput mar an gcéanna leis an gcliant, an t-aon difríocht atá ann ná go léann sé sonraí ón soicéad seachas ón méarchlár. Tá an cód sa stór, díreach cosúil le roghnóir.
Sa chás seo, tá an initialization a chur i bloc ar leith de chód, mar gheall ar laistigh den chur chun feidhme seo, tar éis an t-aistriú a bheith críochnaithe, scaoiltear acmhainní agus déantar iad a athshealbhú arís - arís chun cosaint a sholáthar i gcoinne sceitheadh ​​​​cuimhne.

    private void  incialization()
    {
        try {
            serverSocket = new ServerSocket(port);
            socket = serverSocket.accept();
            sin = socket.getInputStream();
            sout = socket.getOutputStream();
        }
        catch (Exception e) {
            System.out.print(e.getMessage());
        }
    }

Mar achoimre:

Táimid díreach tar éis ár n-éagsúlacht féin a scríobh ar phrótacal aistrithe sonraí simplí agus rinneamar amach conas ba cheart dó oibriú. I bprionsabal, níor tháinig mé ar Mheiriceá anseo agus níor scríobh mé mórán rudaí nua, ach ní raibh ailt dá samhail ar Habré, agus mar chuid de shraith alt a scríobh faoi fhóntais cmd bhí sé dodhéanta gan teagmháil a dhéanamh leis.

Naisc:

Stór cód foinse
Go hachomair faoi TFTP
An rud céanna, ach i Rúisis

Foinse: will.com

Add a comment