আংশিক পাঠে ইউনিক্স স্ট্রিম আনুষঙ্গিক ডেটার সাথে কী ঘটে?


18

সুতরাং আমি ইউনিক্স-স্ট্রিম আনুষঙ্গিক ডেটাতে প্রচুর তথ্য পড়েছি, তবে সমস্ত ডকুমেন্টেশন থেকে একটি জিনিস অনুপস্থিত যা একটি আংশিক পড়া আছে তখন কী ঘটবে বলে মনে করা হচ্ছে?

ধরুন আমি নিম্নলিখিত বার্তাগুলি একটি 24 বাইট বাফারে পেয়েছি

msg1 [20 byes]   (no ancillary data)
msg2 [7 bytes]   (2 file descriptors)
msg3 [7 bytes]   (1 file descriptor)
msg4 [10 bytes]  (no ancillary data)
msg5 [7 bytes]   (5 file descriptors)

Recvmsg- এ প্রথম কলটি, আমি সবগুলি পেয়েছি # 1 (এবং msg2 এর অংশ? ওএস কি কখনও তা করতে পারে?) যদি আমি msg2 এর অংশ পাই, তবে আমি কি এখনই আনুষঙ্গিক ডেটা পেয়েছি এবং পরবর্তী পঠনের জন্য এটি সংরক্ষণ করা দরকার? যখন আমি জানি বার্তাটি আসলে আমাকে ডেটাটি করতে বলছিল কি? আমি যদি # 1 থেকে 20 বাইটগুলি খালি করে দিই এবং পুনরায় recvmsg কল করি তবে এটি কি একই সাথে একবারে msg3 এবং msg4 সরবরাহ করবে? কন্ট্রোল মেসেজ স্ট্রাক্টে কি জিপি 3 এবং ইএসপি 4 এর আনুষঙ্গিক ডেটা সংযুক্ত করা যায়?

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


আমি এখানে আমার পরীক্ষামূলক অনুসন্ধানগুলি যুক্ত করতে যাচ্ছি যা আমি এই পরীক্ষার প্রোগ্রাম থেকে পেয়েছি:

https://github.com/nrdvana/daemonproxy/blob/master/src/ancillary_test.c

লিনাক্স 3.2.59, 3.17.6

দেখা যাচ্ছে যে লিনাক্স অন্য বার্তাগুলির শেষের দিকে আনিসিলারি বহনকারী বার্তাগুলির কিছু অংশ যুক্ত করবে যতক্ষণ না এই কলটি পুনরায় recvmsg এ সরবরাহ করার আগে কোনও পূর্বসূচি পেডলোডের প্রয়োজন হয়। একবার কোনও বার্তার আনুষঙ্গিক ডেটা বিতরণ করা হয়ে গেলে, এটি পরবর্তী সহায়ক-ডেটা বার্তা শুরু করার চেয়ে একটি সংক্ষিপ্ত পঠন ফিরে আসবে। সুতরাং, উপরের উদাহরণে, আমি পঠিতগুলি হ'ল:

recv1: [24 bytes] (msg1 + partial msg2 with msg2's 2 file descriptors)
recv2: [10 bytes] (remainder of msg2 + msg3 with msg3's 1 file descriptor)
recv3: [17 bytes] (msg4 + msg5 with msg5's 5 file descriptors)
recv4: [0 bytes]

বিএসডি 4.4, 10.0

বিএসডি লিনাক্সের চেয়ে আরও প্রান্তিককরণ সরবরাহ করে এবং সহায়ক ডেটা সহ বার্তা শুরুর আগে অবিলম্বে একটি সংক্ষিপ্ত পঠন দেয় । তবে, এটি আনুষঙ্গিকভাবে একটি আনুষাঙ্গিক-বহনকারী বার্তাটির শেষে একটি অ-বিভাগীয়-বহনকারী বার্তা যুক্ত করবে। সুতরাং বিএসডি-র জন্য, দেখে মনে হচ্ছে আপনার বাফারটি সহায়ক-বহন বার্তার চেয়ে বড়, আপনি প্রায় প্যাকেটের মতো আচরণ পান। আমি যে পঠন পাই তা হ'ল:

recv1: [20 bytes] (msg1)
recv2: [7 bytes]  (msg2, with msg2's 2 file descriptors)
recv3: [17 bytes] (msg3, and msg4, with msg3's 1 file descriptor)
recv4: [7 bytes]  (msg5 with 5 file descriptors)
recv5: [0 bytes]

করতে:

এখনও মত জানতে চান কিভাবে এটি পুরোনো লিনাক্স, iOS সোলারিস, ইত্যাদি উপর ঘটে, এবং কিভাবে এটা করতে পারে ভবিষ্যতে ঘটতে হবে বলে আশা করা।


স্ট্রিম এবং প্যাকেটগুলি গুলিয়ে ফেলবেন না, একটি প্রবাহে কোনও প্রকারের গ্যারান্টি নেই যে এটি প্রেরণ করা হয়েছিল সেই একই খণ্ডে ডেটা সরবরাহ করা হবে, এর জন্য আপনার কোনও প্যাকেট ভিত্তিক প্রোটোকল প্রয়োজন, স্ট্রিম ভিত্তিক নয়।
ctrl-alt-delor

ঠিক এই কারণেই আমি এই প্রশ্নটি জিজ্ঞাসা করছি
এম কনরাড

অর্ডার সংরক্ষণ করা উচিত। স্ট্রিমগুলি এটাই করে। যদি কোনও ব্লকিং রিড 0 হয়, তবে এটি স্ট্রিমের সমাপ্তি। যদি এটি অন্য নম্বরটি দেয় তবে আরও কিছু থাকতে পারে, আপনাকে খুঁজে পেতে কমপক্ষে আরও একটি পড়তে হবে। ম্যাসেজ 1, ম্যাসেজ 2 ইত্যাদির মতো কোনও জিনিস নেই কোনও বার্তা ডিলিমিটার প্রেরণ করা হয় না। আপনার প্রোটোকলটিতে এটি যুক্ত করতে হবে, যদি আপনার এটির প্রয়োজন হয়।
ctrl-alt-delor

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

1
@ এমকনরাড: আমি পসিক্স .১ জি স্পেসিফিকেশনটির একটি অনুলিপি পাওয়ার চেষ্টা করব। যদি এটি স্পষ্টভাবে সেখানে লেখা না হয়, তবে আপনি বাস্তবায়ন-নির্দিষ্ট আচরণের আশা করতে পারেন।
লাস্লোলো ভালকো

উত্তর:


1

আনুষঙ্গিক ডেটা এমনভাবে প্রাপ্ত হয় যেন সেগমেন্টে প্রথম সাধারণ ডেটার অক্টেটের সাথে সারি করা থাকে (যদি থাকে)।

- POSIX.1-2017

আপনার বাকী প্রশ্নের জন্য, জিনিসগুলি কিছুটা লোমশ হয়ে উঠেছে।

... এই বিভাগের উদ্দেশ্যে, একটি ডেটাগ্রাম এমন একটি ডেটা বিভাগ হিসাবে বিবেচিত যা একটি রেকর্ড বন্ধ করে দেয় এবং এর মধ্যে একটি উত্স ঠিকানাটি বিশেষ ধরণের আনুষঙ্গিক ডেটা হিসাবে অন্তর্ভুক্ত থাকে।

প্রোটোকল দ্বারা সকেটে ডেটা সরবরাহ করার সাথে সাথে ডেটা বিভাগগুলি কাতারে রাখা হয়। সাধারণ তথ্য বিভাগগুলি বিতরণ করার সাথে সাথে সারির শেষে রাখা হয়। যদি কোনও নতুন বিভাগে পূর্ববর্তী বিভাগের মতো একই ধরণের ডেটা থাকে এবং এতে কোনও আনুষঙ্গিক ডেটা না থাকে এবং পূর্ববর্তী বিভাগটি কোনও রেকর্ডটি বন্ধ না করে, সেগমেন্টগুলি যৌক্তিকভাবে একটি একক বিভাগে মার্জ করা ...

একটি প্রাপ্ত ক্রিয়াকলাপ কখনই একাধিক বিভাগ থেকে ডেটা বা আনুষাঙ্গিক ডেটা ফেরত দেয় না।

সুতরাং আধুনিক বিএসডি সকেটগুলি এই নিষ্কর্ষের সাথে হুবহু মিলে। এটি আশ্চর্যজনক নয় :-)।

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

বিএসডি কোড উল্লেখ না করে লিনাক্স প্রয়োগ করা হয়েছিল। এটি এখানে অন্যরকম আচরণ করে বলে মনে হয়।

  1. যদি আমি আপনাকে সঠিকভাবে পড়ে থাকি তবে মনে হয় লিনাক্স অতিরিক্তভাবে "বিভাগগুলি" মার্জ করে যখন কোনও নতুন বিভাগে আনুষঙ্গিক ডেটা অন্তর্ভুক্ত থাকে তবে পূর্ববর্তী বিভাগটি এতে করে না।

  2. আপনার বক্তব্য যে "লিনাক্স অন্যান্য বার্তাগুলির শেষের দিকে আনিসিলারি বহনকারী বার্তাগুলির অংশ সংযুক্ত করবে যতক্ষণ না এই কলটি পুনর্নির্মাণের সময় সরবরাহের পূর্বে কোনও পূর্বসূচি পেলোড প্রয়োজন হয় না", পুরোপুরি মান দ্বারা ব্যাখ্যা করা হবে না। একটি সম্ভাব্য ব্যাখ্যা একটি দৌড় শর্ত জড়িত হবে। আপনি যদি কোনও "বিভাগ" এর অংশটি পড়েন তবে আপনি আনুষঙ্গিক ডেটা পাবেন। সম্ভবত লিনাক্স এটিকে ব্যাখ্যা করেছেন যার অর্থ এই অংশটির বাকি অংশগুলি সহকারী ডেটা সহ আর গণনা করা হয় না! সুতরাং যখন কোনও নতুন বিভাগটি পাওয়া যায় তখন তা একীভূত হয় - হয় মান অনুসারে বা উপরের পার্থক্য 1 অনুসারে।

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


আপনি তর্ক করতে পারেন লিনাক্স এখনও বেশ কয়েকটি গুরুত্বপূর্ণ নীতি অনুসরণ করে:

  1. "আনুষাঙ্গিক ডেটা এমনভাবে প্রাপ্ত হয়েছে যেন সেগমেন্টে প্রথম সাধারণ ডেটার অক্টেটের সাথে সারি করা হয়"।
  2. আনুষঙ্গিক ডেটা কখনই "মনগড়া" হয় না, যেমন আপনি এটি রেখেছেন put

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

লিনাক্স কার্নেল কোডটি লেখার সময় এটি সম্ভবত বোধগম্য মনে হয়েছিল তবে কোনও প্রোগ্রামের দ্বারা পরীক্ষা বা অনুশীলন না করেই করা হয়েছিল।

অথবা এটি কোনও প্রোগ্রাম কোড দ্বারা অনুশীলন করা যেতে পারে যা বেশিরভাগ এই উপসেটের অধীনে কাজ করে তবে নীতিগতভাবে প্রান্ত-কেস "বাগ" বা বর্ণের শর্ত থাকতে পারে।

আপনি যদি লিনাক্সের আচরণ এবং এর উদ্দেশ্য ব্যবহারটি অনুধাবন করতে না পারেন তবে আমি মনে করি যে এটি লিনাক্সকে "অন্ধকার, অনির্ধারিত কোণ" হিসাবে বিবেচনা করার পক্ষে যুক্তিযুক্ত।


গভীরতা পর্যালোচনার জন্য ধন্যবাদ! আমি মনে করি এখানকার অবতরণের বিষয়টি হ'ল আমি নিরাপদে এটি দুটি বাফার (প্রতিটি অংশের ডেটা এবং আনুষাঙ্গিক অংশ) সহ পরিচালনা করতে পারি; যদি আমি প্রথম পড়তে ফাইল বর্ণনাকারী গ্রহণ করি এবং সেগুলি বার্তার সাথে সম্পর্কিত না হয় তবে অন্য একটি বার্তা শুরু হয়, তবে পরবর্তী পঠনটিতে যদি আনুষঙ্গিক ডেটা থাকে তবে এর অর্থ আমি অবশ্যই প্রথম আনুষঙ্গিক পেডের মালিকানাধীন আমার ডেটা বার্তার শেষ খুঁজে পাব দ্বিতীয় দ্বিতীয় পড়া। পিছনে পিছনে, আমার সর্বদা প্রথম বাইটের অবস্থানের ভিত্তিতে পে-লোডের সাথে বার্তাটি মেলাতে সক্ষম হওয়া উচিত।
এম কনরাড
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.