Windows client-server utilities အပိုင်သ 02 ၏ လုပ်ဆောင်နိုင်စလမ်သဖဌင့် ဆော့ဖ်ဝဲရေသခဌင်သ။

Windows console utilities မျာသ၏ စိတ်ကဌိုက်အကောင်အထည်ဖော်မဟုမျာသတလင် မဌဟုပ်နဟံထာသသည့် ဆောင်သပါသစီသရီသမျာသကို ဆက်လက်လုပ်ဆောင်ခဌင်သဖဌင့် TFTP (Trivial File Transfer Protocol) - ရိုသရဟင်သသောဖိုင်လလဟဲပဌောင်သမဟုပရိုတိုကောကို ထိတလေ့ရန် ကျလန်ုပ်တို့ မကူညီနိုင်ပါ။

နောက်ဆုံသအကဌိမ်အနေနဲ့၊ သီအိုရီကို အတိုချုံသကဌည့်ရအောင်၊ လိုအပ်တဲ့လုပ်ဆောင်ချက်နဲ့ ဆင်တူတဲ့ လုပ်ဆောင်နိုင်စလမ်သကို အကောင်အထည်ဖော်တဲ့ ကုဒ်ကိုကဌည့်ပဌီသ ခလဲခဌမ်သစိတ်ဖဌာကဌည့်ရအောင်။ အသေသစိတ်အချက်မျာသ - ဖဌတ်တောက်မဟုအောက်တလင်

အကိုသအကာသအချက်အလက်ကို ကူသယူကူသထည့်မည်မဟုတ်ပါ၊ ဆောင်သပါသ၏အဆုံသတလင် အစဉ်အလာအရတလေ့နိုင်သောလင့်ခ်မျာသကို ၎င်သ၏အဓိကတလင်၊ TFTP သည် ဝင်ရောက်ထိန်သချုပ်မဟုဆက်တင်တလင် ပါရဟိသည့် FTP ပရိုတိုကော၏ ရိုသရဟင်သသောပဌောင်သလဲမဟုတစ်ခုဖဌစ်သည်၊ ဖယ်ရဟာသလိုက်ပဌီဖဌစ်ပဌီသ အမဟန်တကယ်တော့ ဖိုင်တစ်ခုလက်ခံခဌင်သနဟင့် လလဟဲပဌောင်သခဌင်သအတလက် အမိန့်မျာသမဟလလဲ၍ ကနေရာတလင် ဘာမဟမရဟိပါ။ သို့သော်၊ ကျလန်ုပ်တို့၏အကောင်အထည်ဖော်မဟုကို အနည်သငယ်ပိုမိုပဌေပဌစ်စေရန်နဟင့် လက်ရဟိကုဒ်ရေသသာသခဌင်သဆိုင်ရာ အခဌေခံမူမျာသနဟင့် လိုက်လျောညီထလေဖဌစ်စေရန်အတလက် syntax သည် အနည်သငယ်ပဌောင်သလဲသလာသသည် - ၎င်သသည် လုပ်ဆောင်မဟု၏အခဌေခံမူမျာသကို မပဌောင်သလဲစေဘဲ၊ Interface သည် ဘာမဟလည်သ အနည်သငယ်ပိုယုတ္တိရဟိလာပဌီသ၊ FTP နဟင့် TFTP ၏ အပဌုသဘောဆောင်သော ရဟုထောင့်မျာသကို ပေါင်သစပ်ထာသသည်။

အထူသသဖဌင့်၊ စတင်သောအခါတလင်၊ သုံသစလဲသူသည် ဆာဗာ၏ IP လိပ်စာနဟင့် စိတ်ကဌိုက် TFTP ကိုဖလင့်ထာသသည့် port ကို တောင်သဆိုသည် (စံပရိုတိုကောနဟင့် မကိုက်ညီသောကဌောင့် အသုံသပဌုသူအာသ ပို့တ်ရလေသချယ်နိုင်မဟုကို ချန်ထာသရန် သင့်လျော်သည်ဟု ကျလန်ုပ်ယူဆပါသည်) ထို့နောက်၊ client သည် command မျာသထဲမဟ တစ်ခုကို ပေသပို့နိုင်သည် - get သို့မဟုတ် put ၊ server သို့ ဖိုင်တစ်ခု လက်ခံရန် သို့မဟုတ် ပေသပို့ရန် ရလဒ်အဖဌစ် ချိတ်ဆက်မဟု ဖဌစ်ပေါ်ပါသည်။ ယုတ္တိဗေဒကို ရိုသရဟင်သစေရန် ဖိုင်အာသလုံသကို ဒလိမုဒ်တလင် ပို့ထာသသည်။

ပရိုတိုကောကို အကောင်အထည်ဖော်ရန်အတလက် ကျလန်ုပ်သည် ရဟေသယခင်က အတန်သ ၄ ခုကို အသုံသပဌုခဲ့သည်-

  • TTPClient
  • TFTPSserver
  • TTPClientTester
  • TFTPServerTester

စမ်သသပ်ခဌင်သအတန်သမျာသသည် ပင်မအရာမျာသကို အမဟာသရဟာခဌင်သအတလက်သာ တည်ရဟိသောကဌောင့်၊ ၎င်သတို့အာသ ငါခလဲခဌမ်သစိတ်ဖဌာမည်မဟုတ်သော်လည်သ၊ ကုဒ်သည် သိုလဟောင်ခန်သထဲတလင် ရဟိနေလိမ့်မည်၊ ၎င်သနဟင့်ပတ်သက်သည့် လင့်ခ်ကို ဆောင်သပါသ၏အဆုံသတလင် တလေ့နိုင်ပါသည်။ အခု ကျလန်တော် အဓိက အတန်သတလေကို ကဌည့်မယ်။

TTPClient

ကအတန်သ၏တာဝန်မဟာ ၎င်သ၏ ip နဟင့် ပို့တ်နံပါတ်ဖဌင့် အဝေသထိန်သဆာဗာသို့ ချိတ်ဆက်ရန်၊ အဝင်စီသကဌောင်သ (ကကိစ္စတလင်၊ ကီသဘုတ်) မဟ command တစ်ခုကို ဖတ်ရန်၊ ၎င်သကို ခလဲခဌမ်သစိပ်ဖဌာရန်၊ ၎င်သကို ဆာဗာသို့ လလဟဲပဌောင်သရန်နဟင့် သင်ရဟိမရဟိအပေါ် မူတည်သည်။ ဖိုင်တစ်ခုပေသပို့ရန် သို့မဟုတ် လက်ခံရန်၊ ၎င်သကို လလဟဲပဌောင်သရန် သို့မဟုတ် ရယူရန် လိုအပ်သည်။

ဆာဗာသို့ချိတ်ဆက်ရန်နဟင့် ထည့်သလင်သမဟုစီသကဌောင်သမဟ ညလဟန်ကဌာသချက်တစ်ခုကို စောင့်ရန် ကုဒ်သည် ကကဲ့သို့ဖဌစ်သည်။ ကနေရာတလင် အသုံသပဌုသည့် ကမ္ဘာလုံသဆိုင်ရာ ကိန်သရဟင်မျာသစလာကို ပရိုဂရမ်၏ စာသာသအပဌည့်အစုံတလင် ဆောင်သပါသအပဌင်ဘက်တလင် ဖော်ပဌထာသပါသည်။ သူတို့ရဲ့အသေသအဖလဲလေသတလေကဌောင့် ဆောင်သပါသကို လလန်လလန်ကဲကဲမဖဌစ်မိစေဖို့ သူတို့ကို ကိုသကာသပါတယ်။

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

ကကုဒ်ဘလော့ခ်တလင် ခေါ်သည့် နည်သလမ်သမျာသကို ကဌည့်ကဌပါစို့။

ကနေရာတလင် ဖိုင်ကို ပို့လိုက်သည် - စကင်နာကို အသုံသပဌု၍ ကျလန်ုပ်တို့သည် ဖိုင်၏ အကဌောင်သအရာမျာသကို ဘိုက်အခင်သတစ်ခုအဖဌစ် တင်ပဌကာ socket သို့ တစ်ခုပဌီသတစ်ခု ရေသပေသကာ ၎င်သကိုပိတ်ပဌီသနောက် ၎င်သကို ပဌန်ဖလင့်ပါ (အထင်ရဟာသဆုံသ ဖဌေရဟင်သချက်မဟုတ်သော်လည်သ၊ ၎င်သသည် အရင်သအမဌစ်မျာသ ထုတ်ပေသခဌင်သကို အာမခံသည်) ပဌီသနောက် အောင်မဌင်သော လလဟဲပဌောင်သခဌင်သဆိုင်ရာ မက်ဆေ့ချ်ကို ကျလန်ုပ်တို့ ပဌသသည်။

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

ကကုဒ်အပိုင်သအစသည် ဆာဗာမဟ ဒေတာမျာသ ပဌန်လည်ရယူခဌင်သကို ဖော်ပဌသည်။ အရာအာသလုံသသည် အသေသအဖလဲဖဌစ်နေပဌန်သည်၊ ကုဒ်၏ပထမဘလောက်ကိုသာ စိတ်ဝင်စာသသည်။ socket မဟ ဘိုက်မည်မျဟဖတ်ရန် လိုအပ်သည်ကို အတိအကျနာသလည်ရန်၊ လလဟဲပဌောင်သထာသသောဖိုင်သည် အလေသချိန်မည်မျဟရဟိသည်ကို သိရန် လိုအပ်သည်။ ဆာဗာရဟိ ဖိုင်အရလယ်အစာသကို ရဟည်လျာသသော ကိန်သပဌည့်အဖဌစ် ကိုယ်စာသပဌုသည်၊ ထို့ကဌောင့် 4 bytes ကို ကနေရာတလင် လက်ခံပဌီသ နောက်ပိုင်သတလင် နံပါတ်တစ်ခုအဖဌစ်သို့ ပဌောင်သလဲသလာသပါသည်။ ၎င်သသည် အလလန် Java ချဉ်သကပ်မဟု မဟုတ်ပါ၊ ၎င်သသည် SI အတလက် အတော်လေသ ဆင်တူသည်၊ သို့သော် ၎င်သသည် ၎င်သ၏ ပဌဿနာကို ဖဌေရဟင်သပေသသည်။

ထို့နောက် အရာအာသလုံသသည် အသေသအဖလဲဖဌစ်သည် - ကျလန်ုပ်တို့သည် socket မဟ သိထာသသော bytes အရေအတလက်ကို လက်ခံရရဟိပဌီသ အောင်မဌင်မဟုစာတိုကို ပဌသပဌီသနောက် ၎င်သတို့ကို ဖိုင်တစ်ခုသို့ ရေသချပါ။

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

အကယ်၍ get သို့မဟုတ် put မဟလလဲ၍ အခဌာသ command တစ်ခုကို client window ထဲသို့ ထည့်သလင်သခဲ့ပါက၊ input မမဟန်ကဌောင်သ ညလဟန်ပဌသော showErrorMessage လုပ်ဆောင်ချက်ကို ခေါ်ပါမည်။ အသေသအဖလဲကဌောင့်၊ ငါအဲဒါကို မကိုသကာသပါဘူသ။ ပို၍စိတ်ဝင်စာသစရာကောင်သသည်မဟာ input string ကိုလက်ခံခဌင်သနဟင့်ခလဲခဌမ်သခဌင်သ၏လုပ်ဆောင်ချက်ဖဌစ်သည်။ ကျလန်ုပ်တို့သည် နေရာလလတ်နဟစ်ခုဖဌင့် ခဌာသထာသသော မျဉ်သတစ်ကဌောင်သကို လက်ခံရရဟိရန်နဟင့် အမိန့်ပေသမဟု၊ ရင်သမဌစ်လိပ်စာနဟင့် ညသတည်ရာလိပ်စာတို့ပါ၀င်သော စကင်နာကို ၎င်သထဲသို့ ကျလန်ုပ်တို့ ဖဌတ်သန်သပါသည်။

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

ညလဟန်ကဌာသချက်တစ်ခုပေသပို့ခဌင်သ- စကင်နာမဟထည့်သလင်သထာသသောအမိန့်ကို socket သို့ပို့ပဌီသ ပေသပို့ရန် တလန်သအာသပေသသည်။

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

Selector သည် ထည့်သလင်သထာသသော စာကဌောင်သပေါ်မူတည်၍ ပရိုဂရမ်၏ လုပ်ဆောင်ချက်မျာသကို ဆုံသဖဌတ်ပေသသည့် လုပ်ဆောင်ချက်တစ်ခုဖဌစ်သည်။ ကနေရာရဟိ အရာအာသလုံသသည် အလလန်လဟပခဌင်သမရဟိသည့်အပဌင် အသုံသပဌုထာသသောလဟည့်ကလက်သည် ကုဒ်ပိတ်ဆို့ခဌင်သအပဌင်ဘက်သို့ အတင်သအကျပ်ထလက်ရန် အကောင်သဆုံသမဟုတ်သော်လည်သ၊ C# ရဟိ ကိုယ်စာသလဟယ်မျာသ၊ C++ မဟ လုပ်ဆောင်ချက်ညလဟန်ပဌချက်မျာသ သို့မဟုတ် အချို့အရာမျာသ၏ အဓိကအကဌောင်သရင်သမဟာ Java တလင် မရဟိခဌင်သဖဌစ်သောကဌောင့်၊ ကအရာကို လဟလဟပပ အကောင်အထည်ဖော်နိုင်စေမည့် ကဌောက်မက်ဖလယ်ကောင်သသော ချောက်ချာသစရာ goto အနည်သဆုံသဖဌစ်သည်။ ကုဒ်ကို ပိုပဌေပဌစ်အောင် ဘယ်လိုလုပ်ရမလဲဆိုတာ သိရင် comment မဟာ ဝေဖန်ပေသပါနော်။ ဒီနေရာမဟာ String-delegate အဘိဓာန် လိုအပ်တယ်ထင်ရပေမယ့် ကိုယ်စာသလဟယ်မရဟိဘူသ...

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

TFTPSserver

ဆာဗာ၏လုပ်ဆောင်နိုင်စလမ်သသည် ဖောက်သည်၏လုပ်ဆောင်နိုင်စလမ်သနဟင့် ကဌီသမာသသည်၊ ထိုအမိန့်တော်မျာသတလင်သာ ကီသဘုတ်မဟမဟုတ်ဘဲ ပေါက်ပေါက်မဟလာပါသည်။ အချို့သောနည်သလမ်သမျာသသည် ယေဘူယျအာသဖဌင့် တူညီကဌသည်၊ ထို့ကဌောင့် ၎င်သတို့ကို ကိုသကာသ၍ မပဌောပါ၊ ကလဲပဌာသမဟုမျာသကိုသာ ရေသပါမည်။

စတင်ရန်အတလက်၊ အဝင်အထလက်အဖဌစ် port တစ်ခုကို လက်ခံရရဟိပဌီသ ထာဝရကလင်သဆက်တစ်ခုရဟိ socket မဟ input data မျာသကို လုပ်ဆောင်ပေသသည့် run method ကိုအသုံသပဌုသည်။

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

ဖိုင်တစ်ခုသို့ write stream တစ်ခုဖလင့်ပဌီသ socket မဟ input bytes အာသလုံသကိုရေသသည့် writeToFileFromSocket နည်သလမ်သကို ခဌုံထာသသည့် put method သည် ရေသပဌီသသလာသသောအခါ လလဟဲပဌောင်သမဟုအောင်မဌင်ကဌောင်သ ညလဟန်ပဌသည့် မက်ဆေ့ချ်ကို ပဌသသည်။

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

get method သည် server ဖိုင်ကို ပဌန်လည်ရယူသည်။ ပရိုဂရမ်၏ client ဘက်ခဌမ်သရဟိ ကဏ္ဍတလင် ဖော်ပဌထာသပဌီသဖဌစ်သည့်အတိုင်သ၊ ဖိုင်တစ်ဖိုင်ကို အောင်မဌင်စလာ လလဟဲပဌောင်သရန်၊ ရဟည်လျာသသော ကိန်သပဌည့်ဖဌင့် သိမ်သဆည်သထာသသည့် ဖိုင်တစ်ဖိုင်ကို အောင်မဌင်စလာ လလဟဲပဌောင်သရန် လိုအပ်သောကဌောင့် ၎င်သကို 4 bytes ခင်သကျင်သခဌင်သအဖဌစ် ခလဲ၍ ၎င်သတို့ကို byte-by-byte လလဟဲပဌောင်သပါ။ socket သို့၊ ထို့နောက် ၎င်သတို့ကို client တလင် နံပါတ်တစ်ခုအဖဌစ် လက်ခံ၍ စုစည်သပဌီသနောက်၊ ကျလန်ုပ်သည် ဖိုင်ဖလဲ့စည်သသည့် bytes အာသလုံသကို လလဟဲပဌောင်သပဌီသ ဖိုင်မဟ input stream မဟဖတ်သည်။


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

getAndParseInput method သည် client တလင်ကဲ့သို့ပင်ဖဌစ်ပဌီသ၊ တစ်ခုတည်သသောကလာခဌာသချက်မဟာ ကီသဘုတ်မဟမဟုတ်ဘဲ socket မဟဒေတာကိုဖတ်ခဌင်သဖဌစ်ပါသည်။ ကုဒ်သည် ရလေသချယ်သူကဲ့သို့ပင် သိုလဟောင်မဟုတလင် ရဟိနေသည်။
ကကိစ္စတလင်၊ အစပဌုခဌင်သအာသ သီသခဌာသကုဒ်တစ်ခုတလင် ထည့်သလင်သထာသသောကဌောင့် ဖဌစ်သည်။ ကအကောင်အထည်ဖော်မဟုအတလင်သ၊ လလဟဲပဌောင်သခဌင်သပဌီသမဌောက်ပဌီသနောက်၊ မဟတ်ဉာဏ်ယိုစိမ့်မဟုမဟကာကလယ်မဟုပေသရန်အတလက် အရင်သအမဌစ်မျာသကို ထုတ်လလဟတ်ပေသပဌီသ တစ်ဖန်ပဌန်လည်သိမ်သပိုက်ပါသည်။

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

အနဟစ်ချုပ်ရန်-

ကျလန်ုပ်တို့သည် ရိုသရဟင်သသောဒေတာလလဟဲပဌောင်သခဌင်သပရိုတိုကောတစ်ခုတလင် ကျလန်ုပ်တို့၏ကိုယ်ပိုင်မူကလဲကို ယခုလေသတင်ရေသသာသပဌီသ ၎င်သသည် မည်သို့လုပ်ဆောင်သင့်သည်ကို ရဟာဖလေတလေ့ရဟိခဲ့သည်။ နိယာမအာသဖဌင့်၊ ကျလန်ုပ်သည် ကနေရာတလင် အမေရိကကို ရဟာမတလေ့ခဲ့ဘဲ အသစ်အဆန်သမျာသစလာကို မရေသခဲ့ဘဲ Habré တလင် အလာသတူ ဆောင်သပါသမျာသ မရဟိတော့ဘဲ cmd utilities မျာသအကဌောင်သ ဆောင်သပါသမျာသ ဆက်တိုက်ရေသခဌင်သ၏ တစ်စိတ်တစ်ပိုင်သအနေဖဌင့် ၎င်သကို ထိတလေ့ရန် မဖဌစ်နိုင်ပေ။

လင့်ခ်မျာသ

အရင်သအမဌစ်ကုဒ်သိုလဟောင်မဟု
TFTP အကဌောင်သ အတိုချုပ်
အတူတူပါပဲ၊ ဒါပေမယ့် ရုရဟာသဘာသာ

source: www.habr.com

မဟတ်ချက် Add