যখন আমরা নেটওয়ার্কিং এর কথা বলি, তখন আমরা OSI মডেল উল্লেখ করতে ব্যর্থ হতে পারি না।

এই মডেলের পরিপ্রেক্ষিতে, আজ আমরা পরিবহন স্তরে সবচেয়ে বেশি আগ্রহী (4)।

এটি সেই স্তর যেখানে আমরা ডেটা নিয়ে কাজ করি "বিন্দু A থেকে বি পয়েন্টে"। পরিবহন স্তরের প্রধান কাজ হল সঠিক ক্রম বজায় রেখে একটি বার্তা গন্তব্যে পৌঁছে দেওয়া নিশ্চিত করা। দুটি সবচেয়ে সাধারণ পরিবহন স্তর প্রোটোকল হল: TCP এবং UDP। তারা ধারণাগতভাবে বিভিন্ন উপায়ে কাজ করে, তবে প্রতিটির নিজস্ব সুবিধা রয়েছে যা তাদের নির্দিষ্ট সমস্যাগুলি সমাধান করতে দেয়।

প্রথমে, আসুন দেখি কিভাবে TCP কাজ করে।

TCP (ট্রান্সমিশন কন্ট্রোল প্রোটোকল) হল একটি নেটওয়ার্ক প্রোটোকল যা নিশ্চিত করে যে ডেটা আদান-প্রদানের আগে হোস্টগুলির মধ্যে একটি সংযোগ স্থাপন করা হয়েছে।

এটি একটি অত্যন্ত নির্ভরযোগ্য প্রোটোকল, কারণ প্রতিবার এটি অন্য ডেটা প্যাকেট পাঠালে, এটি অবশ্যই পরীক্ষা করতে হবে যে পূর্বের প্যাকেটটি গ্রহণ করা হয়েছে।

প্রেরিত প্যাকেট অর্ডার করা হয়, এবং যদি একটি নির্দিষ্ট প্যাকেটের সাথে সমস্যা হয় (অর্থাৎ গ্রহণকারী পক্ষ নিশ্চিত করে না যে প্যাকেটটি এসেছে), তাহলে প্যাকেটটি আবার পাঠানো হয়। ফলস্বরূপ, স্থানান্তরের হার তুলনামূলকভাবে কম, কারণ কঠোর পর্যবেক্ষণের জন্য এবং সঠিক অর্ডার নিশ্চিত করার জন্য আরও সময় প্রয়োজন।

এখানেই এর "ভাই", UDP প্রোটোকল আসে। TCP এর বিপরীতে, UDP প্রতিটি প্যাকেটের ক্রম এবং স্থিতি সম্পর্কে সত্যিই চিন্তা করে না। এটি কেবল ডেলিভারি নিশ্চিতকরণ ছাড়াই ডেটা পাঠায়। আরও কী, এটি কোনও সংযোগ স্থাপন করে না এবং কোনওভাবেই সংযোগের অবস্থার উপর নির্ভর করে না।

এর উদ্দেশ্য হল একটি ঠিকানায় ডেটা পাঠানো। এবং এটি প্রোটোকলের প্রধান অসুবিধা, কম নির্ভরযোগ্যতার জন্ম দেয়, যেহেতু এটি কেবল ডেটার টুকরো হারাতে পারে। অতিরিক্তভাবে, প্রাপককে অবশ্যই প্রস্তুত থাকতে হবে যে ডেটা অর্ডারের বাইরে আসতে পারে। এটি বলেছে, প্রোটোকলের একটি সুবিধাও রয়েছে, একটি উচ্চ স্থানান্তর হার, কারণ প্রোটোকলটি ডেটা পাঠানোর মধ্যে সীমাবদ্ধ।

ডেটা নিজেই কীভাবে প্রেরণ করা হয় তার মধ্যেও পার্থক্য রয়েছে। TCP-তে, ডেটা স্ট্রিম করা হয়, যার মানে ডেটার কোনও সীমানা নেই। UDP-তে, ডেটা ডেটাগ্রাম হিসাবে প্রেরণ করা হয় এবং এর সীমানা রয়েছে এবং প্রাপক ডেটার অখণ্ডতা পরীক্ষা করে, তবে শুধুমাত্র যদি বার্তাটি সফলভাবে প্রাপ্ত হয়।

আসুন সংক্ষিপ্ত করা যাক:

টিসিপি একটি নির্ভরযোগ্য এবং সঠিক প্রোটোকল যা ডেটা ক্ষতি প্রতিরোধ করে। একটি বার্তা সর্বদা সর্বাধিক নির্ভুলতার সাথে বিতরণ করা হবে, বা মোটেও বিতরণ করা হবে না। প্রাপকের ডেটা অর্ডার করার জন্য যুক্তির প্রয়োজন নেই, যেহেতু ইনকামিং ডেটা ইতিমধ্যেই অর্ডার করা হবে। UDP ততটা নির্ভরযোগ্য নয়, কিন্তু এটি একটি দ্রুত ডেটা ট্রান্সফার প্রোটোকল। এই প্রোটোকলের সাথে কাজ করার জন্য পাঠানো এবং গ্রহণকারী পক্ষের কিছু অতিরিক্ত যুক্তির প্রয়োজন। কিন্তু নেটওয়ার্কে খেলা কম্পিউটার গেম বা মোবাইল গেমের উদাহরণ ব্যবহার করে এটি কীভাবে কাজ করে তা দেখে নেওয়া যাক। 5 সেকেন্ড আগে কী পৌঁছানো উচিত ছিল তা নিয়ে আমরা আর চিন্তা করতে পারি না, এবং সময়মতো না পৌঁছালে আমরা কয়েকটি প্যাকেট এড়িয়ে যেতে পারি — গেমটি পিছিয়ে যেতে পারে, কিন্তু আপনি এখনও খেলতে পারেন!

জাভাতে, UDP এর মাধ্যমে প্রেরিত ডেটাগ্রামের সাথে কাজ করার জন্য, আমরা DatagramSocket এবং DatagramPacket ক্লাসের অবজেক্ট ব্যবহার করি।

ডেটা বিনিময় করার জন্য, প্রেরক এবং প্রাপক ডেটাগ্রাম সকেট তৈরি করে, যেমন ডেটাগ্রাম সকেট ক্লাসের উদাহরণ। ক্লাসের বেশ কিছু কনস্ট্রাক্টর আছে। তাদের মধ্যে পার্থক্য হল যেখানে তৈরি সকেট সংযোগ করবে:

ডেটাগ্রাম সকেট () স্থানীয় মেশিনে উপলব্ধ যেকোনো পোর্টের সাথে সংযোগ করে
ডেটাগ্রাম সকেট (int পোর্ট) স্থানীয় মেশিনে নির্দিষ্ট পোর্টের সাথে সংযোগ করে
ডেটাগ্রাম সকেট (int পোর্ট, InetAddress ঠিকানা) স্থানীয় মেশিনে একটি ঠিকানায় নির্দিষ্ট পোর্টের সাথে সংযোগ করে (addr)

ক্লাসে সকেট প্যারামিটারগুলি অ্যাক্সেস এবং পরিচালনা করার জন্য অনেকগুলি পদ্ধতি রয়েছে (আমরা সেগুলিকে একটু পরে দেখব), সেইসাথে ডেটাগ্রামগুলি গ্রহণ এবং প্রেরণের পদ্ধতিগুলি রয়েছে:

পাঠান (ডেটাগ্রাম প্যাকেট প্যাক) প্যাকেটে প্যাক করা ডেটাগ্রাম পাঠায়
গ্রহণ (ডেটাগ্রাম প্যাকেট প্যাক) প্যাকেটে প্যাক করা ডেটাগ্রাম গ্রহণ করে

DatagramPacket হল একটি ক্লাস যা একটি ডেটাগ্রাম প্যাকেজ প্রতিনিধিত্ব করে। ডেটাগ্রাম প্যাকেটগুলি একটি সংযোগহীন প্যাকেট বিতরণ পরিষেবা বাস্তবায়ন করতে ব্যবহৃত হয়। প্রতিটি বার্তা শুধুমাত্র সেই প্যাকেটে থাকা তথ্যের ভিত্তিতে এক মেশিন থেকে অন্য মেশিনে পাঠানো হয়। এক মেশিন থেকে অন্য মেশিনে পাঠানো একাধিক প্যাকেট ভিন্নভাবে রুট করা হতে পারে এবং যেকোনো ক্রমে আসতে পারে। প্যাকেট ডেলিভারি নিশ্চিত করা হয় না.

নির্মাণকারী:

ডেটাগ্রাম প্যাকেট (বাইট [] buf, int দৈর্ঘ্য) দৈর্ঘ্য দৈর্ঘ্যের প্যাকেট গ্রহণ করার জন্য একটি ডেটাগ্রাম প্যাকেট তৈরি করে ।
DatagramPacket(byte[] buf, int length, InetAddress ঠিকানা, int পোর্ট) নির্দিষ্ট হোস্টে নির্দিষ্ট পোর্ট নম্বরে দৈর্ঘ্যের দৈর্ঘ্যের প্যাকেট পাঠাতে একটি ডেটাগ্রাম প্যাকেট তৈরি করে ।
ডেটাগ্রাম প্যাকেট (বাইট [] buf, int অফসেট, int দৈর্ঘ্য) বাফারে একটি অফসেট উল্লেখ করে দৈর্ঘ্যের দৈর্ঘ্যের প্যাকেট গ্রহণ করার জন্য একটি DatagramPacket তৈরি করে।
DatagramPacket(byte[] buf, int অফসেট, int দৈর্ঘ্য, InetAddress ঠিকানা, int পোর্ট) নির্দিষ্ট হোস্টে নির্দিষ্ট পোর্ট নম্বরে অফসেট অফসেট সহ দৈর্ঘ্যের দৈর্ঘ্যের প্যাকেট পাঠাতে একটি ডেটাগ্রাম প্যাকেট তৈরি করে ।
DatagramPacket(byte[] buf, int অফসেট, int length, SocketAddress ঠিকানা) নির্দিষ্ট হোস্টে নির্দিষ্ট পোর্ট নম্বরে অফসেট অফসেট সহ দৈর্ঘ্যের দৈর্ঘ্যের প্যাকেট পাঠাতে একটি ডেটাগ্রাম প্যাকেট তৈরি করে ।
DatagramPacket(byte[] buf, int length, SocketAddress ঠিকানা) নির্দিষ্ট হোস্টে নির্দিষ্ট পোর্ট নম্বরে দৈর্ঘ্যের দৈর্ঘ্যের প্যাকেট পাঠাতে একটি ডেটাগ্রাম প্যাকেট তৈরি করে ।

আমরা স্মরণ করি যে UDP পদ্ধতি একটি সংযোগ স্থাপন করে না। প্রাপক তাদের প্রত্যাশা করছেন এমন আশায় প্যাকেটগুলি পাঠানো হয়। কিন্তু আপনি DatagramSocket ক্লাসের connect(InetAddress addr, int পোর্ট) পদ্ধতি ব্যবহার করে একটি সংযোগ স্থাপন করতে পারেন।

ঠিকানা এবং পোর্টের উপর ভিত্তি করে হোস্টের সাথে একটি একমুখী সংযোগ স্থাপন করা হয়: হয় ডেটাগ্রাম পাঠাতে বা গ্রহণ করতে। সংযোগটি disconnect() পদ্ধতি ব্যবহার করে বন্ধ করা যেতে পারে।

ডাটা প্রাপ্তির জন্য DatagramSocket এর উপর ভিত্তি করে সার্ভার কোড লেখার চেষ্টা করি :


import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

class Recipient {

   public static void main(String[] args) {
       try {
           DatagramSocket ds = new DatagramSocket(1050);

           while (true) {
               DatagramPacket pack = new DatagramPacket(new byte[5], 5);
               ds.receive(pack);
               System.out.println(new String(pack.getData()));
           }
       } catch (IOException e) {
           e.printStackTrace();
       }
   }
}

আমরা পোর্ট 1050 এ শোনার জন্য একটি DatagramSocket অবজেক্ট তৈরি করি। যখন এটি একটি বার্তা পায়, এটি কনসোলে প্রিন্ট করে। আমরা "হ্যালো" শব্দটি প্রেরণ করব, তাই আমরা বাফারের আকার পাঁচ বাইটে সীমাবদ্ধ করব।

এখন আমরা প্রেরক ক্লাস তৈরি করব:


import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

class Sender {
   private String host;
   private int port;

   Sender(String host, int port) {
       this.host = host;
       this.port = port;
   }

   private void sendMessage(String mes) {
       try {
           byte[] data = mes.getBytes();
           InetAddress address = InetAddress.getByName(host);
           DatagramPacket pack = new DatagramPacket(data, data.length, address, port);
           DatagramSocket ds = new DatagramSocket();
           ds.send(pack);
           ds.close();
       } catch (IOException e) {
           System.err.println(e);
       }
   }

   public static void main(String[] args) {
   Sender sender = new Sender("localhost", 1050);
   String message = "Hello";

   Timer timer = new Timer();
   timer.scheduleAtFixedRate(new TimerTask() {
       @Override
       public void run() {
           sender.sendMessage(message);
       }
   }, 1000, 1000);
}

}

sendMessage পদ্ধতিতে , আমরা একটি DatagramPacket এবং DatagramSocket তৈরি করি এবং আমাদের বার্তা পাঠাই। নোট করুন যে বার্তা পাঠানোর পরে DatagramSocket বন্ধ করতে close() পদ্ধতি ব্যবহার করা হয়।

প্রতি সেকেন্ডে প্রাপকের কনসোল প্রেরকের প্রেরিত ইনকামিং "হ্যালো" বার্তা প্রদর্শন করে। এর মানে হল যে আমাদের যোগাযোগ সঠিকভাবে কাজ করছে।