Ukubhala isoftware enomsebenzi weWindows client-server eziluncedo, icandelo 02

Ukuqhubela phambili uluhlu oluqhubekayo lwamanqaku anikezelwe ekuphunyezweni kwesiko lezinto eziluncedo ze-Windows console, asinakukwazi ukuzibamba kwi-TFTP (iProtokholi yokuGqithisela kweFayile encinci) - iprotocol elula yokudlulisa iifayile.

Njengexesha lokugqibela, masihambe ngokufutshane kwithiyori, sibone ikhowudi ephumeza ukusebenza ngokufana nefunekayo, kwaye siyihlalutye. Iinkcukacha ezongezelelweyo - phantsi kokunqunyulwa

Andiyi kukopa-uncamathisele ulwazi lwereferensi, amakhonkco apho ngokwesiko anokufumaneka ekupheleni kwenqaku, ndiya kuthetha kuphela ukuba kumbindi wayo, i-TFTP lulwahlulo olulula lweprotocol ye-FTP, apho isicwangciso solawulo lofikelelo sinakho. isusiwe, kwaye eneneni akukho nto apha ngaphandle kwemiyalelo yokwamkela nokudluliselwa kwefayile . Nangona kunjalo, ukwenza ukuphunyezwa kwethu kube kuhle ngakumbi kwaye kuhlengahlengiswe kwimigaqo yangoku yekhowudi yokubhala, i-syntax itshintshiwe kancinane - oku akuyitshintshi imigaqo yokusebenza, kodwa i-interface, i-IMHO, iba yingqiqo ngakumbi kwaye idibanisa imiba emihle ye-FTP kunye ne-TFTP.

Ngokukodwa, xa iqalisiwe, umxhasi ucela idilesi ye-IP yomncedisi kunye nezibuko apho i-TFTP yesiko ivuliwe (ngenxa yokungahambelani nomgaqo oqhelekileyo, ndibone kufanelekile ukushiya umsebenzisi amandla okukhetha izibuko), emva koko a uxhulumaniso lwenzeka, ngenxa yoko umxhasi angathumela enye yemiyalelo - ukufumana okanye ukubeka, ukufumana okanye ukuthumela ifayile kumncedisi. Zonke iifayile zithunyelwa kwimo yokubini ukwenza lula ingqiqo.

Ukuphumeza iprotocol, ngokwesiko ndandisebenzisa iiklasi ezi-4:

  • TFTPClient
  • TFTPSserver
  • TFTPClientTester
  • TFTPSserverTester

Ngenxa yokuba iiklasi zokuvavanya zikhona kuphela ukulungisa iimpazamo eziphambili, andiyi kuzihlalutya, kodwa ikhowudi iya kuba kwindawo yokugcina; Ngoku ndiza kujonga kwiiklasi eziphambili.

TFTPClient

Umsebenzi wolu didi kukudibanisa kwiseva ekude usebenzisa ip yayo kunye nenombolo yezibuko, funda umyalelo ovela kumjelo wegalelo (kulo mzekelo, ibhodi yezitshixo), yahlulahlule, uyidlulisele kumncedisi, kwaye, kuxhomekeke ekubeni unakho na. Kufuneka uthumele okanye ufumane ifayile, uyigqithisele okanye uyifumane.

Ikhowudi yokuqalisa umxhasi ukudibanisa kumncedisi kwaye ulinde umyalelo ovela kumjelo wegalelo ibonakala ngolu hlobo. Inani lezinto eziguquguqukayo zehlabathi ezisetyenziswa apha zichazwe ngaphandle kwenqaku, kumbhalo opheleleyo weprogram. Ngenxa yobuncinci bazo, andizicaphuli ukuze ndingafaki kakhulu inqaku.

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

Makhe sijonge iindlela ezibizwa kule block yekhowudi:

Apha ifayile ithunyelwa - usebenzisa i-scanner, sinika imixholo yefayile njengoluhlu lwee-bytes, esizibhala nganye nganye kwi-socket, emva koko siyivale kwaye siyivule kwakhona (kungekhona isisombululo esicacileyo, kodwa iqinisekisa ukukhutshwa kwezibonelelo), emva koko sibonisa umyalezo malunga nokudluliselwa ngempumelelo.

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

Esi siqwenga sekhowudi sichaza ukubuyisela idatha kwiseva. Yonke into iphinda ibe yinto encinci, kuphela ibhloko yokuqala yekhowudi enomdla. Ukuze uqonde kakuhle ukuba zingaphi ii-bytes ezifuna ukufundwa kwi-socket, kufuneka ukwazi ukuba ifayile edluliselweyo inzima kangakanani. Ubungakanani befayile kumncedisi bumelwe njengenani elipheleleyo, ngoko ke iibytes ezi-4 zamkelwe apha, ezithi emva koko ziguqulelwe zibe linani elinye. Le ayisiyondlela yeJava kakhulu, iyafana ne-SI, kodwa iyayisombulula ingxaki yayo.

Emva koko yonke into iyinto encinci - sifumana inani elaziwayo leebhayithi ukusuka kwisokhethi kwaye sibhale kwifayile, emva koko sibonisa umyalezo oyimpumelelo.

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

Ukuba umyalelo ngaphandle kokufumana okanye ukufakwa bekungeniswa kwifestile yomxhasi, umsebenzi we-showErrorMessage uya kubizwa, ebonisa ukuba igalelo belingalunganga. Ngenxa yobuncinci, andizukuyikhankanya. Kancinci umdla ngakumbi ngumsebenzi wokufumana kunye nokwahlula umtya wegalelo. Sidlulisela iskena kuyo, apho silindele ukufumana umgca ohlulwe ngezithuba ezibini kwaye uqulethe umyalelo, idilesi yomthombo kunye nedilesi yendawo.

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

Ukuthumela umyalelo-uthumela umyalelo ongenisiweyo ukusuka kwiskena ukuya kwisokethi kwaye uyawunyanzela ukuba uthunyelwe

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

Umkhethi ngumsebenzi omisela iintshukumo zenkqubo ngokuxhomekeke kuluhlu olungenisiweyo. Yonke into apha ayintle kakhulu kwaye iqhinga elisetyenzisiweyo ayisiyiyo eyona ilungileyo ngokuphuma ngenkani ngaphandle kwebhloko yekhowudi, kodwa esona sizathu siphambili soku kukungabikho kweJava kwezinye izinto, njengabathunywa kwiC #, izikhombisi zomsebenzi ezivela kwiC ++, okanye kwi. ubuncinci igoto eyoyikisayo neyoyikekayo, ekuvumela ukuba uphumeze oku ngobuhle. Ukuba uyayazi indlela yokwenza ikhowudi ibentle ngakumbi, ndiyakwamkela ukugxekwa kwizimvo. Kubonakala kum ngathi isichazi-magama se-String-delegate siyafuneka apha, kodwa akukho mthunywa...

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

TFTPSserver

Ukusebenza komncedisi kuyahluka ekusebenzeni komxhasi, ngokubanzi, kuphela kuloo miyalelo iza kuyo kungekhona kwibhodibhodi, kodwa isuka kwisiseko. Ezinye zeendlela eziqhelekileyo ziyafana, ngoko andiyi kubanika, ndiya kuchukumisa kuphela ukungafani.

Ukuqala, indlela yokuqhuba isetyenzisiweyo, efumana i-port njengegalelo kwaye iqhubekisela phambili idatha yegalelo kwi-socket kwi-loop yanaphakade.

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

Indlela yokubeka, esonga indlela yokubhalaToFileFromSocket evula umlambo wokubhala kwifayile kwaye ibhale zonke ii-bytes zokufaka kwi-socket, ibonisa umyalezo obonisa ukugqitywa ngempumelelo kokudluliselwa xa ukubhala kugqityiwe.

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

Indlela yokufumana ifumana kwakhona ifayile yomncedisi. Njengoko sele kukhankanyiwe kwicandelo kwicala lomxhasi weprogram, ukudlulisa ngempumelelo ifayile kufuneka uyazi ubungakanani bayo, igcinwe kwinani elipheleleyo elipheleleyo, ngoko ke ndiyahlulahlula kuluhlu lwee-bytes ezi-4, ndigqithise i-byte-by-byte. kwi-socket, kwaye emva koko, emva kokuba ndifumene kwaye ndibahlanganisele kumxhasi kwinombolo emva, ndidlulisela zonke ii-bytes ezenza ifayile, zifunde ukusuka kumlambo wegalelo kwifayile.


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

Indlela ye getAndParseInput iyafana nakumxhasi, umahluko kuphela kukuba ifunda idatha kwisokethi kunokuba isuka kwibhodi yezitshixo. Ikhowudi ikwindawo yokugcina, kanye njengomkhethi.
Kule meko, ukuqaliswa kufakwe kwibhloko eyahlukileyo yekhowudi, kuba ngaphakathi kolu phunyezo, emva kokuba ukudluliselwa kugqityiwe, izibonelelo zikhululwa kwaye ziphinde zihlalwe kwakhona - kwakhona ukubonelela ngokhuseleko malunga nokuvuza kweememori.

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

Ukushwankathela:

Sisanda kubhala ukwahluka kwethu kwiprotocol elula yokudlulisa idatha kwaye sicinge ukuba kufuneka isebenze njani. Ngokomgaqo, andizange ndifumane iMelika apha kwaye andizange ndibhale izinto ezininzi ezintsha, kodwa kwakungekho manqaku afanayo kuHabrΓ©, kwaye njengenxalenye yokubhala uluhlu lwamanqaku malunga nezixhobo ze-cmd kwakungenakwenzeka ukuba ungachukumisi kuyo.

Izalathiso:

Indawo yokugcina ikhowudi yomthombo
Ngokufutshane malunga ne-TFTP
Into efanayo, kodwa ngesiRashiya

umthombo: www.habr.com

Yongeza izimvo