2011-04-08 12 views
5

मैं एक छोटी पर्ल लर्निंग प्रोजेक्ट के माध्यम से काम करने की कोशिश कर रहा हूं जिसके लिए सॉकेट से 4 हस्ताक्षरित पूर्णांक पढ़ने की आवश्यकता है। मैं 1 से अधिक पूर्णांक पढ़ नहीं पाया, और चारों ओर खोदने के बाद मुझे एक समाधान मिला। लेकिन मैं समझने के लिए मैं सही नहीं किया क्या जरूरतसॉकेट-> आरईवी() बनाम <>?

उदाहरण 1 (और कोई लाभ नहीं हुआ पर्ल किताबें, perldocs, आदि के एक जोड़े के माध्यम से चले गए हैं।): यहाँ सफल समाधान कोड (original) है, मान लेते हैं सॉकेट कनेक्ट नीचे दोनों के लिए सफल है:

{ 
    local $/ = \16; # make <> read in 16 bytes with one swoop. 
    my @integers = unpack "IIII", <$sock>; 
    print "numbers: @val\n"; 
} 

उदाहरण 2: मैंने इसे नीचे करने की कोशिश की।

my $input; 
$sock->recv($input,16,0); 
my @integers = unpack("IIII", $input); 

विशिष्ट सवाल:

  1. उदाहरण 1 में, क्या बिल्ली है "$ /" अगर मैं खोल से पहले इनपुट प्रिंट, मैं केवल एक पूर्णांक मिल सकता है? और यह <> कैसे बदलता है, जिसे मैंने सोचा था STDIN?
  2. उदाहरण 2 में, क्या कोई कारण है कि मेरा recv() सॉकेट से एक से अधिक पूर्णांक नहीं लेता है? मेरी समझ (प्रति perldoc) यह है कि "SIZE" पैरामीटर "बाइट्स" पर डिफ़ॉल्ट है, और पूर्णांक 4 बाइट्स हैं?

कोई भी मदद, पॉइंटर्स इत्यादि की सराहना की जाती है। बीटीडब्ल्यू, "लर्निंग प्रोजेक्ट" overthewire.org है - बहुत अच्छी चीजें।

+1

सरल दस्तावेज सामग्री को रास्ते से बाहर निकालने के लिए: [perlvar $ /] (http://p3rl.org/var#%24INPUT_RECORD_SEPARATOR); '<>' [readline] के लिए सिर्फ एक अलग नाम है (http://p3rl.org/readline) – daxim

उत्तर

1

1 के रूप में)

खैर, <> सॉकेट सहित किसी भी filehandles, लेता है। यह सम्मेलन है कि आप इसे खाली छोड़ सकते हैं, इस मामले में किसी प्रकार का सौदा डिफ़ॉल्ट व्यवहार माना जाता है। perldoc perlop देखें (<> के अंदर खोजें)।

और विशेष चर $/ रिकॉर्ड विभाजक है और यह "\ n" पर डिफ़ॉल्ट है। आप इसे अनदेखा कर सकते हैं और पूरी फाइल को एक बार में पढ़ सकते हैं (जिसे स्लरपिंग कहा जाता है)। अधिक के लिए perldoc perlvar देखें (\number केस भी है)।

+0

यह मेरे लिए काम करता है, हालांकि मैंने सभी टिप्पणियों का उपयोग किया था। मैं काम करने के लिए कभी पढ़/रीडलाइन/आरईवी नहीं प्राप्त कर सकता था। लेकिन अब मैं समझता हूं कि <> और $/का उपयोग कैसे करें, मैं आगे बढ़ रहा हूं। सहायता के लिए धन्यवाद। – 1111000110

4

क्या आपका सॉकेट टीसीपी या यूडीपी है?

recv<>/readline से कम-स्तर की दिनचर्या है। यह recv(2) सिस्टम कॉल पर सीधे या उससे कम मानचित्र बनाता है। यदि सॉकेट डेटा 4 4-बाइट पैकेट के रूप में आ रहा है, recv पहले पैकेट को देखने के तुरंत बाद वापस आ जाएगा, भले ही इसे एक बड़ा बफर प्रदान किया गया हो। यदि सभी 4 पैकेट पहले कॉल से पहले recv() पर पहुंचते हैं, तो क्या आपको सभी डेटा मिलते हैं या केवल एक टुकड़ा संभवतः यह निर्भर करता है कि यह टीसीपी या यूडीपी है या नहीं।

यदि आप टीसीपी का उपयोग कर रहे हैं, तो संभावना है कि पैकेट उड़ान में विभाजित हो जाएंगे। 16 बाइट पेलोड के साथ होने की संभावना नहीं है, लेकिन सबसे अच्छा अभ्यास यह नहीं मानना ​​चाहिए कि डेटा के 16 बाइट एक बार में दिखाई देंगे, भले ही आपको पता है कि सर्वर ने इसे एक बार में भेजा है। नेटवर्क अनुप्रयोगों को आमतौर पर आने वाले डेटा को बफर करने की अपेक्षा की जाती है, या, आप $/ = \16 के साथ 16-बाइट रिकॉर्ड निर्दिष्ट करके यह आपके लिए कर सकते हैं।

एक और संभावना है, जो मैं आई/ओ उपयोग के इस तरह के <> की तुलना में अधिक प्राकृतिक मिल जाए, read या sysread कार्य (या OO समकक्ष है, जो IO::Socket सुपर क्लास IO::Handle में परिभाषित कर रहे हैं) का प्रयोग है।वे एक लंबी तर्क लेते हैं, लेकिन पहले की तरह, आपको यह नहीं मानना ​​चाहिए कि पूरा बफर एक बार भर जाएगा।

1

read और readline (उर्फ <>) लौटने से पहले अनुरोध की गई राशि की प्रतीक्षा की प्रतीक्षा करें। यह केवल त्रुटि या ईओएफ की स्थिति में कम वर्ण लौटाएगा, इस मामले में अगला पठन एक त्रुटि या ईओएफ वापस करेगा।

sysread जैसे ही कुछ वर्ण उपलब्ध हैं, भले ही अनुरोधित राशि से कम हों।

आप जो कह रहे हैं उसके आधार पर, recvsysread जैसा है। यदि आप 16 वर्ण चाहते हैं, तो आपको लूप करना होगा जब तक कि आपके पास 16 वर्ण हों या read या readline का उपयोग न करें।