د وینډوز مراجعینو-سرور اسانتیاوو فعالیت سره د سافټویر لیکلو برخه، 02 برخه

د وینډوز کنسول اسانتیاو دودیز پلي کولو ته وقف شوي مقالو روانې لړۍ ته دوام ورکول ، موږ نشو کولی د TFTP (Trivial File Transfer Protocol) سره مرسته وکړو - د فایل لیږد یو ساده پروتوکول.

د تیر ځل په څیر، راځئ چې په لنډه توګه تیوري ته لاړ شو، هغه کوډ وګورئ چې د اړتیا وړ ورته ورته فعالیت پلي کوي، او تحلیل یې کړئ. نور جزئیات - د کټ لاندې

زه به د حوالې معلومات کاپي پیسټ نه کړم، لینکونه چې په دودیز ډول د مقالې په پای کې موندل کیدی شي، زه به یوازې ووایم چې د هغې په اصلي برخه کې، TFTP د FTP پروتوکول یو ساده بدلون دی، په کوم کې چې د لاسرسي کنټرول ترتیب لري. لرې شوی، او په حقیقت کې دلته د فایل ترلاسه کولو او لیږدولو امرونو پرته بل څه نشته. په هرصورت ، د دې لپاره چې زموږ پلي کول یو څه ښکلي او د لیکلو اوسني اصولو سره تطابق شي ، ترکیب یو څه بدل شوی - دا د عملیاتو اصول نه بدلوي ، مګر انٹرفیس ، IMHO ، یو څه ډیر منطقي کیږي او د FTP او TFTP مثبت اړخونه یوځای کوي.

په ځانګړي توګه ، کله چې پیل شو ، پیرودونکي د سرور IP پتې او هغه بندر غوښتنه کوي چې په کوم کې دودیز TFTP خلاص دی (د معیاري پروتوکول سره د نه مطابقت له امله ، ما دا مناسبه وګڼله چې کارونکي ته د بندر غوره کولو وړتیا پریږدم) ، له هغې وروسته اتصال رامینځته کیږي ، د دې په پایله کې پیرودونکي کولی شي یو له امرونو څخه واستوي - ترلاسه کړئ یا واچوئ ، سرور ته د فایل ترلاسه کولو یا لیږلو لپاره. ټول فایلونه په بائنری حالت کې لیږل شوي ترڅو منطق ساده کړي.

د پروتوکول پلي کولو لپاره ، ما په دودیز ډول 4 ټولګي کارولي:

  • TFTPC مراجعین
  • TFTPSسرور
  • TFTPClientTester
  • TFTPServerTester

د دې حقیقت له امله چې د ازموینې ټولګي یوازې د اصلي ډیبګ کولو لپاره شتون لري ، زه به یې تحلیل نه کړم ، مګر کوډ به په ذخیره کې وي؛ د دې لپاره لینک د مقالې په پای کې موندل کیدی شي. اوس زه به اصلي ټولګیو ته وګورم.

TFTPC مراجعین

د دې ټولګي دنده دا ده چې د ریموټ سرور سره د هغې د IP او پورټ شمیرې سره وصل شي ، د ان پټ سټریم څخه کمانډ ولولئ (پدې حالت کې ، کیبورډ) ، دا پارس کړئ ، سرور ته یې لیږدئ ، او پدې پورې اړه لري چې ایا تاسو د فایل لیږلو یا ترلاسه کولو ته اړتیا لرئ، لیږدول یا ترلاسه کړئ.

د سرور سره وصل کولو لپاره د پیرودونکي پیل کولو کوډ او د ان پټ سټریم څخه د قوماندې انتظار کولو لپاره داسې ښکاري. یو شمیر نړیوال تغیرات چې دلته کارول کیږي د مقالې څخه بهر د برنامې په بشپړ متن کې تشریح شوي. د دوی د نیمګړتیا له امله ، زه دوی ته اشاره نه کوم ترڅو مقاله ډیر نه کړي.

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

راځئ چې د کوډ په دې بلاک کې ویل شوي میتودونو ته لاړ شو:

دلته فایل لیږل کیږي - د سکینر په کارولو سره ، موږ د فایل مینځپانګې د بایټس په توګه وړاندې کوو ، کوم چې موږ یو له بل سره ساکټ ته لیکو ، وروسته لدې چې موږ یې وتړو او بیا یې خلاص کړو (تر ټولو څرګند حل ندی ، مګر دا د سرچینو خوشې کول تضمینوي)، له هغې وروسته موږ د بریالي لیږد په اړه پیغام ښکاره کوو.

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

دا کوډ ټوټه د سرور څخه د معلوماتو بیرته ترلاسه کول تشریح کوي. هرڅه بیا کوچني دي ، یوازې د کوډ لومړی بلاک د علاقې وړ دی. د دې لپاره چې دقیقا پوه شئ چې د ساکټ څخه څومره بایټ لوستلو ته اړتیا لري ، تاسو اړتیا لرئ پوه شئ چې لیږدول شوي فایل څومره وزن لري. په سرور کې د فایل اندازه د اوږد انټیجر په توګه ښودل کیږي، نو دلته 4 بایټونه منل شوي، چې وروسته بیا په یوه شمیره بدلیږي. دا د جاوا ډیره طریقه نه ده، دا د SI لپاره ورته دی، مګر دا د هغې ستونزه حل کوي.

بیا هرڅه کوچني دي - موږ د ساکټ څخه د بایټونو پیژندل شوي شمیر ترلاسه کوو او په فایل کې یې لیکو، له هغې وروسته موږ د بریالیتوب پیغام ښکاره کوو.

   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 پرته بل قومانده داخله شوې وي ، نو د showErrorMessage فنکشن به ویل کیږي ، دا په ګوته کوي چې ننوت غلط و. د نیمګړتیا له امله، زه به یې حواله نه کړم. یو څه ډیر په زړه پوري د ان پټ سټینګ ترلاسه کولو او ویشلو فعالیت دی. موږ سکینر په دې کې لیږدوو، له کوم څخه چې موږ تمه لرو چې یوه کرښه ترلاسه کړو چې د دوو ځایونو لخوا جلا شوي او کمانډ، سرچینې پته او د منزل پته لري.

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

د قوماندې لیږل - د سکینر څخه ساکټ ته داخل شوي کمانډ لیږدوي او د لیږلو لپاره یې مجبوروي

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

انتخاب کونکی یو فنکشن دی چې د ننوتلو تار پورې اړه لري د برنامې کړنې ټاکي. دلته هرڅه خورا ښکلي ندي او کارول شوي چال د کوډ بلاک څخه بهر د جبري وتلو سره غوره نه دی ، مګر د دې اصلي لامل په جاوا کې د ځینې شیانو نشتوالی دی ، لکه په C# کې استازي ، د C++ څخه فنکشن پوائنټرونه ، یا په لږترلږه یو ډارونکی او ویرونکی ګوتو، کوم چې تاسو ته اجازه درکوي دا په ښکلي ډول پلي کړئ. که تاسو پوهیږئ چې څنګه کوډ یو څه ډیر په زړه پوری کړئ ، زه په نظرونو کې انتقاد ته ښه راغلاست وایم. ماته داسې ښکاري چې دلته د سټرینګ - استازو قاموس ته اړتیا ده ، مګر هیڅ استازی شتون نلري ...

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

TFTPSسرور

د سرور فعالیت د پیرودونکي له فعالیت څخه توپیر لري ، په لویه کچه ، یوازې پدې کې کمانډونه د کیبورډ څخه نه ، بلکه له ساکټ څخه راځي. ځینې ​​میتودونه عموما ورته دي، نو زه به یې په ګوته نه کړم، زه به یوازې توپیرونو ته اشاره وکړم.

د پیل کولو لپاره، د چلولو طریقه کارول کیږي، کوم چې د ان پټ په توګه پورټ ترلاسه کوي او د ساکټ څخه د ان پټ ډاټا په ابدي لوپ کې پروسس کوي.

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

د پټولو میتود، کوم چې د writeToFileFromSocket میتود پوښي چې فایل ته د لیکلو جریان خلاصوي او د ساکټ څخه ټول ان پټ بایټونه لیکي، یو پیغام ښیې چې د لیږد بریالي بشپړتیا په ګوته کوي کله چې لیکل بشپړ شي.

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

د ترلاسه کولو میتود د سرور فایل ترلاسه کوي. لکه څنګه چې دمخه د برنامه د پیرودونکي اړخ برخه کې یادونه شوې ، په بریالیتوب سره د فایل لیږدولو لپاره تاسو اړتیا لرئ د هغې اندازه وپیژنئ ، په اوږد انټیجر کې زیرمه شوی ، نو ما دا د 4 بایټ په صف کې ویشلی ، د بایټ په واسطه یې لیږدوي. ساکټ ته، او بیا، په مراجعینو کې یې په یوه شمیره کې ترلاسه او راټولول، زه ټول بایټونه لیږدوم چې فایل جوړوي، د فایل څخه د ان پټ جریان څخه لوستل کیږي.


 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 میتود د پیرودونکي په څیر ورته دی ، یوازینی توپیر دا دی چې دا د کیبورډ پرځای د ساکټ څخه ډاټا لوستل کیږي. کوډ په ذخیره کې دی، لکه د انتخاب کونکي په څیر.
په دې حالت کې، پیل کول د کوډ په جلا بلاک کې ځای پرځای شوي، ځکه چې د دې پلي کولو په جریان کې، د لیږد بشپړیدو وروسته، سرچینې خوشې کیږي او بیا ځای پرځای کیږي - بیا د حافظې لیکو پروړاندې محافظت چمتو کولو لپاره.

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

د لنډیز لپاره:

موږ یوازې د ساده معلوماتو لیږد پروتوکول کې خپل توپیر لیکلی او معلومه کړې چې دا باید څنګه کار وکړي. په اصولو کې، ما دلته امریکا نه ده موندلې او ډیر نوي شیان یې نه دي لیکلي، مګر په هابري کې ورته مقالې شتون نلري، او د cmd افادیتونو په اړه د یو لړ مقالو لیکلو برخې په توګه دا ناشونې وه چې په دې باندې لاس ونه وهل شي.

سرچینې:

د سرچینې کوډ ذخیره
په لنډه توګه د TFTP په اړه
ورته شی، مګر په روسیه کې

سرچینه: www.habr.com

Add a comment