পাঠ ২৬ · ৫৭-এর মধ্যে · মডিউল ৫
Home / Courses / Computer Networks / স্লাইডিং উইন্ডো

ফ্লো কন্ট্রোল — স্লাইডিং উইন্ডো

Flow control — sliding window
৮ মিনিট পড়া মধ্যবর্তী · Intermediate Python কোডসহ সম্পূর্ণ বাংলায়

এই পাঠে যা শিখবেন

  • ফ্লো কন্ট্রোল ঠিক কোন সমস্যা সমাধান করে ও কেন এটি একটি রিসিভার-সাইড ধারণা
  • স্টপ-অ্যান্ড-ওয়েট বনাম স্লাইডিং উইন্ডোর মধ্যে দক্ষতার পার্থক্য
  • উইন্ডো কীভাবে ACK আসার সাথে সাথে "স্লাইড" করে সামনে এগোয়
  • Python দিয়ে একটি স্লাইডিং উইন্ডো সেন্ডারের সিমুলেশন

১ · ফ্লো কন্ট্রোল কোন সমস্যা সমাধান করে

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

ফ্লো কন্ট্রোল বনাম কনজেশন কন্ট্রোল — গুরুত্বপূর্ণ পার্থক্য

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

২ · স্লাইডিং উইন্ডো — স্টপ-অ্যান্ড-ওয়েটের চেয়ে ভালো

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

স্লাইডিং উইন্ডোSliding Window Protocolরিসিভারের বিজ্ঞাপিত window size পর্যন্ত একাধিক সেগমেন্ট একসাথে "ইন-ফ্লাইট" (পাঠানো কিন্তু এখনও অ্যাকনলেজড-না-হওয়া) রাখার প্রোটোকল — ACK আসার সাথে সাথে উইন্ডো সামনে এগোয়। প্রোটোকল অনেক বেশি দক্ষ — রিসিভার একটি window size বিজ্ঞাপন দেয় (এখন কতটা অ্যাকনলেজড-না-হওয়া ডেটা বাফার করতে ইচ্ছুক), আর সেন্ডার প্রতিটি পৃথক ACK-এর জন্য অপেক্ষা না করেই সেই সীমা পর্যন্ত একাধিক সেগমেন্ট একসাথে পাঠাতে পারে। ACK আসার সাথে সাথে উইন্ডো সামনের দিকে "স্লাইড" করে, নতুন ডেটা পাঠানোর জায়গা খুলে দেয়।

সব সেগমেন্ট: ১ ২ ৩ ৪ ৫ ৬ ৭ (মোট ৭টি পাঠাতে হবে) উইন্ডো (আকার ৩) — ধাপ ১ উইন্ডো ACK পাওয়ার পর সামনে সরে গেছে — ধাপ ৩
প্রতিটি ACK-এর জন্য পুরো থেমে না থেকে, উইন্ডো ধীরে ধীরে সামনের দিকে সরে গিয়ে নতুন সেগমেন্ট পাঠানোর জায়গা করে দেয়।
Python
# স্লাইডিং উইন্ডো সেন্ডার সিমুলেশন — টয় ইন-মেমরি ডেটা, কোনো প্রকৃত নেটওয়ার্ক নয়

segments = [f"সেগমেন্ট-{i}" for i in range(1, 8)]  # মোট ৭টি সেগমেন্ট পাঠাতে হবে
window_size = 3  # রিসিভারের বিজ্ঞাপিত receive window

def send_with_sliding_window(segments, window_size, ack_schedule):
    """ack_schedule[step] = সেই ধাপে কতগুলো নতুন সেগমেন্ট অ্যাকনলেজড হলো (একটি নির্ধারিত, fixed প্যাটার্ন)।"""
    sent = 0
    acked = 0
    step = 0
    log = []
    while acked < len(segments):
        in_flight = sent - acked
        can_send = min(window_size - in_flight, len(segments) - sent)
        newly_sent = []
        for _ in range(max(can_send, 0)):
            newly_sent.append(segments[sent])
            sent += 1
        new_acks = ack_schedule[step] if step < len(ack_schedule) else 0
        acked += min(new_acks, sent - acked)
        log.append({
            "ধাপ": step + 1,
            "নতুন পাঠানো": newly_sent,
            "মোট পাঠানো": sent,
            "মোট acked": acked,
            "in-flight": sent - acked,
        })
        step += 1
    return log

ack_schedule = [0, 1, 1, 2, 1, 1, 1]  # প্রতি ধাপে কতটি নতুন ACK আসল (নির্ধারিত প্যাটার্ন)

log = send_with_sliding_window(segments, window_size, ack_schedule)
for entry in log:
    print(entry)

print("\nপ্রতিটি ধাপে in-flight কখনো window_size ছাড়ায়নি?",
      all(entry["in-flight"] <= window_size for entry in log))
print("শেষে সব সেগমেন্ট acked হয়েছে?", log[-1]["মোট acked"] == len(segments))

    
লক্ষ্য করুন — ধাপ ১-এ সেন্ডার সরাসরি ৩টি সেগমেন্ট (পুরো উইন্ডো) পাঠিয়ে দেয়, কোনো ACK-এর জন্য অপেক্ষা না করেই। স্টপ-অ্যান্ড-ওয়েট হলে এখানে সেন্ডারকে প্রতিটি সেগমেন্টের পর আলাদা করে থামতে হতো — window_size=৩ মানে এখানে ৩ গুণ বেশি ডেটা একসাথে "পথে" থাকতে পারছে, লিংক অনেক কম অলস সময় কাটাচ্ছে।
মূল কথা · Key takeaway

স্লাইডিং উইন্ডো ফ্লো কন্ট্রোলকে থ্রুপুট বলি না দিয়েই বাস্তবায়ন করে — রিসিভার তার নিজের ক্ষমতা অনুযায়ী window size নিয়ন্ত্রণ করে, আর সেন্ডার সেই সীমার মধ্যেই যতটা সম্ভব সমান্তরালভাবে ডেটা পাঠায়। L27-এ আমরা দেখব কনজেশন কন্ট্রোল কীভাবে একটি সম্পূর্ণ ভিন্ন, দ্বিতীয় একটি সীমা (cwnd) যোগ করে — এবার নেটওয়ার্ক পাথ রক্ষা করার জন্য।

ভাবনার প্রশ্ন

প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।

প্র ০১ window_size=১ (মূলত স্টপ-অ্যান্ড-ওয়েট) ব্যবহার করলে উপরের কোডের আচরণ কীভাবে বদলাত?

প্রতিটি ধাপে সর্বোচ্চ ১টি সেগমেন্ট পাঠানো যেত, এবং সেন্ডারকে তার ACK না আসা পর্যন্ত নতুন কিছু পাঠাতে হতো না — এটি কার্যকরভাবে স্টপ-অ্যান্ড-ওয়েট আচরণ তৈরি করত। মোট সেগমেন্ট পাঠাতে অনেক বেশি ধাপ লাগত, কারণ একসাথে একাধিক সেগমেন্ট "ইন-ফ্লাইট" রাখার কোনো সুযোগই থাকত না।

প্র ০২ যদি রিসিভারের বাফার হঠাৎ ভরে যায়, রিসিভার কী করতে পারে?

রিসিভার তার পরবর্তী ACK-এ একটি ছোট (এমনকি শূন্য) window size বিজ্ঞাপন দিতে পারে — একে "zero window" বলে। সেন্ডার তখন নতুন ডেটা পাঠানো বন্ধ রাখে যতক্ষণ না রিসিভার তার বাফার খালি করে বড় window size আবার বিজ্ঞাপন দেয় — এভাবেই ফ্লো কন্ট্রোল গতিশীলভাবে রিসিভারের প্রকৃত ক্ষমতার সাথে সামঞ্জস্য রাখে।

প্র ০৩ ফ্লো কন্ট্রোল ও কনজেশন কন্ট্রোল উভয়ই সেন্ডারের গতি সীমিত করে — বাস্তবে সেন্ডার কীভাবে ঠিক করে কতটা পাঠাবে যদি দুটি ভিন্ন সীমা থাকে?

বাস্তব TCP সবসময় দুটির মধ্যে ছোটটি ব্যবহার করে — রিসিভারের বিজ্ঞাপিত receive window এবং সেন্ডারের নিজস্ব congestion window (cwnd, L27) — যেটি ছোট, ইন-ফ্লাইট ডেটার প্রকৃত সীমা সেটিই হয়ে দাঁড়ায়। এভাবে TCP নিশ্চিত করে সে একই সাথে রিসিভারকে ডুবিয়ে ফেলে না, আবার নেটওয়ার্ক পাথকেও ওভারলোড করে না।

অনুশীলন

  1. চিন্তা করুন: উপরের কোড সেলে window_size ১-এ পরিবর্তন করে Run চেপে দেখুন লগে কতগুলো ধাপ লাগে, এবং তা window_size=৩-এর ফলাফলের সাথে তুলনা করুন।

    window_size=১-এ প্রতিটি ধাপে সর্বোচ্চ একটি সেগমেন্ট "ইন-ফ্লাইট" থাকতে পারবে, ফলে সম্পূর্ণ ৭টি সেগমেন্ট পাঠাতে (একই ack_schedule দিয়ে হলেও) বেশি ধাপ লাগবে — কারণ সেন্ডার একবারে অনেক কম ডেটা "সমান্তরালে" রাখতে পারছে, বেশিরভাগ সময় একটি মাত্র ACK-এর অপেক্ষায় কাটছে।

  2. পরীক্ষা করুন: window_size ৭ (সব সেগমেন্টের সমান) করে দিন এবং লক্ষ্য করুন ধাপ ১-এই কী ঘটে।

    window_size=৭ মানে সেন্ডার প্রথম ধাপেই সবগুলো সেগমেন্ট (সবক'টি) একসাথে পাঠিয়ে দিতে পারবে, কারণ উইন্ডো এতটাই বড় যে সব সেগমেন্ট একসাথে "ইন-ফ্লাইট" থাকার জায়গা করে দেয় — এটি দেখায় বড় window_size থাকা মানে সেন্ডার তত বেশি সমান্তরাল ডেটা পাঠাতে পারে, যতক্ষণ রিসিভারের বাফার তা সামলাতে পারে।

আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ

আগের পাঠ
L25 · TCP রিলায়েবল ডেলিভারি — সিকোয়েন্স নাম্বার ও ACK