আমার পরামর্শের জন্য, দয়া করে শেষ বিভাগটি পড়ুন: "কখন টাইমআউট 0 এর সাথে SO_LINGER ব্যবহার করবেন" ।
আমরা এই সম্পর্কে একটি সামান্য বক্তৃতা আসার আগে:
- সাধারণ টিসিপি সমাপ্তি
TIME_WAIT
FIN
, ACK
এবংRST
সাধারণ টিসিপি সমাপ্তি
সাধারণ টিসিপি সমাপ্তির ক্রমটি এর মতো দেখায় (সরলীকৃত):
আমাদের দুটি সমকক্ষ রয়েছে: এ এবং বি
- একটি কল
close()
- এ
FIN
বি কে প্রেরণ করে
- ক
FIN_WAIT_1
রাজ্যে যায়
- বি পায়
FIN
- বি পাঠায়
ACK
ক তে
- বি
CLOSE_WAIT
রাজ্যে যায়
- এ গ্রহণ করে
ACK
- বি কল
close()
- বি পাঠায়
FIN
ক তে
- বি
LAST_ACK
রাজ্যে যায়
- এ গ্রহণ করে
FIN
- এ
ACK
বি কে প্রেরণ করে
- ক
TIME_WAIT
রাজ্যে যায়
- বি পায়
ACK
- বি
CLOSED
স্টেটে যায় - অর্থাৎ সকেট টেবিল থেকে সরানো হয়
চভভ
সুতরাং সমাপ্তি - অর্থাত close()
প্রথম কল - - সমাপ্তির সূচনা করে এমন পিয়ারটি TIME_WAIT
রাজ্যে শেষ হবে ।
TIME_WAIT
রাষ্ট্রটি কেন আমাদের বন্ধু তা বুঝতে , দয়া করে স্টিভেনস এট আল (পৃষ্ঠা 43) র তৃতীয় সংস্করণ "ইউনিক্স নেটওয়ার্ক প্রোগ্রামিং" এর ২.7 অংশটি পড়ুন।
তবে TIME_WAIT
কোনও সার্ভারে প্রচুর সকেট থাকা অবস্থায় এটি সমস্যা হতে পারে কারণ এটি শেষ পর্যন্ত নতুন সংযোগগুলি গ্রহণযোগ্যতা থেকে রোধ করতে পারে।
এই সমস্যাটি সমাধান করার জন্য, আমি অনেককে কল করার আগে টাইমআউট 0 এর সাথে SO_LINGER সকেট বিকল্প সেট করার পরামর্শ দিয়েছি close()
। যাইহোক, এটি একটি খারাপ সমাধান কারণ এটি টিসিপি সংযোগটি ত্রুটির সাথে বন্ধ করে দেয়।
পরিবর্তে, আপনার অ্যাপ্লিকেশন প্রোটোকলটি ডিজাইন করুন যাতে সংযোগ সমাপ্তকরণ সর্বদা ক্লায়েন্টের পক্ষ থেকে শুরু করা হয়। যদি ক্লায়েন্ট সর্বদা জানে যে এটি কখন বাকী সমস্ত ডেটা পড়েছে তবে এটি সমাপ্তির ক্রমটি শুরু করতে পারে। উদাহরণস্বরূপ, কোনও ব্রাউজার Content-Length
এইচটিটিপি শিরোনামের কাছ থেকে জানে যখন এটি সমস্ত ডেটা পড়ে এবং বন্ধটি শুরু করতে পারে। (আমি জানি যে HTTP 1.1 এ এটি সম্ভাব্য পুনঃব্যবহারের জন্য এটি কিছু সময়ের জন্য উন্মুক্ত রাখবে এবং তারপরে এটি বন্ধ করে দেবে))
সার্ভারটির যদি সংযোগটি বন্ধ করার দরকার হয় তবে অ্যাপ্লিকেশন প্রোটোকলটি ডিজাইন করুন যাতে সার্ভার ক্লায়েন্টকে কল করতে বলে close()
।
সময়সীমা 0 সহ কখন SO_LINGER ব্যবহার করবেন
আবার, "ইউনিক্স নেটওয়ার্ক প্রোগ্রামিং" তৃতীয় সংস্করণ পৃষ্ঠা 202-203 অনুসারে, SO_LINGER
কল করার আগে টাইমআউট 0 এর সাথে সেট করার close()
ফলে স্বাভাবিক সমাপ্তির ক্রমটি শুরু না হওয়ার কারণ হবে ।
পরিবর্তে, পিয়ার এই বিকল্পটি সেট করে এবং কলিং close()
একটি RST
(সংযোগ পুনরায় সেট) প্রেরণ করবে যা একটি ত্রুটির অবস্থার ইঙ্গিত দেয় এবং অন্য প্রান্তে এটি কীভাবে উপলব্ধি করা হবে। আপনি সাধারণত "পিয়ারের মাধ্যমে সংযোগ পুনরায় সেট করার" মতো ত্রুটি দেখতে পাবেন।
সুতরাং, সাধারণ পরিস্থিতিতে SO_LINGER
কল করার আগে টাইমআউট 0 দিয়ে সেট করা সত্যিই খারাপ ধারণা close()
- এখন থেকে গর্ভপাত বন্ধ বলা - একটি সার্ভার অ্যাপ্লিকেশনটিতে।
যাইহোক, নির্দিষ্ট পরিস্থিতিতে পরোয়ানা যাইহোক এটি করে:
- যদি আপনার সার্ভার অ্যাপ্লিকেশনটির কোনও ক্লায়েন্ট খারাপ আচরণ করে (সময় শেষ হয়ে যায়, অবৈধ ডেটা ফেরত দেয়, ইত্যাদি) যদি কোনও গর্ভপাত বন্ধ হয়ে যায়
CLOSE_WAIT
তবে TIME_WAIT
রাষ্ট্রটিতে আটকা পড়া বা শেষ হওয়া এড়াতে হবে ।
- যদি আপনাকে অবশ্যই আপনার সার্ভার অ্যাপ্লিকেশনটি পুনরায় চালু করতে হবে যার বর্তমানে হাজার হাজার ক্লায়েন্ট সংযোগ রয়েছে আপনি হাজার হাজার সার্ভার সকেটগুলিতে এড়াতে এই সকেট বিকল্পটি সেট করার কথা বিবেচনা করতে পারেন
TIME_WAIT
( close()
সার্ভার শেষ থেকে কল করার সময় ) কারণ এটি সার্ভারকে নতুন ক্লায়েন্ট সংযোগের জন্য উপলব্ধ পোর্টগুলি পেতে বাধা দিতে পারে পুনরায় চালু হওয়ার পরে।
- উপরোক্ত গ্রন্থে পৃষ্ঠা 202 এটা বিশেষভাবে বলছে: "কিছু পরিস্থিতিতে এক ব্যর্থ ঘনিষ্ঠ পাঠাতে এই বৈশিষ্ট্য ব্যবহার পরোয়ানা আছে একটা উদাহরণ একটি RS-- 232 টার্মিনাল সার্ভার, যা চিরকাল স্তব্ধ পারে।
CLOSE_WAIT
একটি আটকে টার্মিনালে তথ্য প্রদান করা চেষ্টা পোর্ট, তবে আটকে থাকা পোর্টটি সঠিকভাবে পুনরায় সেট করতে হবে যদি এটি RST
মুলতুবি থাকা ডেটা বাতিল করতে পারে "
আমি এই দীর্ঘ নিবন্ধটি সুপারিশ করব যা আমার বিশ্বাস আপনার প্রশ্নের একটি খুব ভাল উত্তর দেয়।