2011-11-13 21 views
7

की मैं कैसे और क्यों निम्नलिखित कोड खंडों काम को समझने में असमर्थ हूँ:प्रभाव SO_SNDBUF

/* Now lets try to set the send buffer size to 5000 bytes */ 
    size = 5000; 
    err = setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(int)); 
    if (err != 0) { 
     printf("Unable to set send buffer size, continuing with default size\n"); 
    } 

हम भेजने बफर के मूल्य की जाँच करते हैं, तो यह वास्तव में सही ढंग से 5000 * 2 = 10000 पर सेट है हालांकि, अगर हम भेजने वाले बफर आकार से अधिक भेजने का प्रयास करते हैं, तो यह सब कुछ भेजता है। उदाहरण के लिए:

n = send(sockfd, buf, 30000, 0); 

    /* Lets check how much us actually sent */ 
    printf("No. of bytes sent is %d\n", n); 

यह बाहर प्रिंट 30000

वास्तव में यह काम किया है कैसे? क्या तथ्य यह नहीं था कि प्रेषण बफर आकार 10000 तक सीमित था, इसका कोई प्रभाव नहीं पड़ा? अगर ऐसा हुआ, तो वास्तव में क्या हुआ? कुछ प्रकार का विखंडन?

अद्यतन: सॉकेट गैर-अवरोध मोड में होने पर क्या होता है? 10000 (5000 * 2) 16384 बाइट्स का कारण बनता भेजे जाने के लिए

  • को

    1. बदलने बफर आकार बफर आकार बदलने 20000 (10000 * 2) का कारण बनता है के लिए 30000 बाइट्स
    भेजे जाने के लिए: मैं निम्नलिखित की कोशिश की

    एक बार फिर, क्यों?

  • उत्तर

    11

    SO_SNDBUF विकल्प सेट करने का प्रभाव टीसीपी और यूडीपी के लिए अलग है।

    • यूडीपी के लिए यह आंकड़ारेख के आकार पर सीमा है, यानी बड़ा कुछ भी त्याग दिया जाएगा निर्धारित करता है।
    • टीसीपी के लिए यह दिए गए सॉकेट के लिए इन-कर्नेल बफर का आकार सेट करता है (पृष्ठ सीमा तक और ऊपरी सीमा के साथ कुछ गोल करने के साथ)।

    चूंकि यह लगता है कि आप टीसीपी के बारे में बात कर रहे हैं, प्रभाव आप देख रहे हैं सॉकेट में किया जा रहा मोड, तो गिरी जब तक send(2) ब्लॉकों अपने सभी डेटा के स्वीकार कर सकते हैं, और/या नेटवर्क को अवरुद्ध करके समझाया गया है अतुल्यकालिक रूप से डी-क्यूइंग डेटा ढेर करें और इसे नेटवर्क कार्ड पर दबाएं, इस प्रकार बफर में स्थान खाली कर दें।

    इसके अलावा, टीसीपी स्ट्रीम प्रोटोकॉल है, यह किसी भी "संदेश" संरचना को संरक्षित नहीं करता है। एक send(2) दूसरी तरफ कई recv(2) एस और दूसरी तरफ से मेल खा सकता है। बाइट-स्ट्रीम के रूप में इसका इलाज करें।

    +0

    और क्या होता है यदि सॉकेट गैर-अवरोध मोड में है? मैंने निम्नलिखित कोशिश की: 1) 10000 तक बफर आकार बदलने के कारण 16384 बाइट्स भेजे जाने के कारण 2) 20000 तक बफर आकार बदलना 30000 बाइट्स भेजा जा सकता है एक बार फिर, क्यों? – Arun

    +0

    @ अरुण: यह सिर्फ गोल है .. यह बिल्कुल क्यों मायने रखता है? आपको इस तथ्य पर भरोसा नहीं करना चाहिए कि बफर * बिल्कुल * एन बाइट्स है। कर्नेल अधिक आवंटित कर सकते हैं। –

    +1

    सबसे पहले, कर्नेल आपके बफर आकार को उतना ही नहीं लेता है, जैसा कि @yi_H इंगित करता है। फिर, नेटवर्क स्टैक आपकी प्रक्रिया के संबंध में * असीमित * संचालित करता है। निम्न का प्रयास करें - सॉकेट पर लिखना शुरू करें, लेकिन * अन्य आकार * पर न पढ़ें।आखिरकार आपको एक छोटा सा मिलेगा (कर्नेल कम बाइट स्वीकार करता है तो आप इसे देते हैं) या असफल लिखते हैं। –

    4

    SO_SNDBUF सॉफ़्ट कार्यान्वयन आंतरिक रूप से उपयोग किए जाने वाले बफर को कॉन्फ़िगर करता है। यदि आपकी सॉकेट गैर-अवरुद्ध है तो आप केवल कॉन्फ़िगर किए गए आकार को भेज सकते हैं, अगर आपकी सॉकेट अवरुद्ध हो रही है तो आपके कॉल के लिए कोई सीमा नहीं है।

    संबंधित मुद्दे