2012-09-29 19 views
9

send() भेजे गए बाइट्स या त्रुटि कोड की संख्या वापस कर देगा, लेकिन मुझे मिले सभी उदाहरण केवल त्रुटि कोड के साथ जांचते हैं, लेकिन बाइट्स की संख्या के साथ नहीं।क्या भेजता है() सभी बफर भेजते हैं?

//typical example 
int cnt=send(s,query,strlen(query),0); 
if (cnt < 0) return(NULL); 
//Hey, what about cnt < strlen(query)? 

उत्तर

13

प्रश्न: क्या "भेजें()" हमेशा पूरे बफर को वापस करता है?

ए: नहीं, जरूरी नहीं।

बीज की गाइड से: * http://beej.us/guide/bgnet/output/html/multipage/syscalls.html#sendrecv

भेजने() रिटर्न बाइट की संख्या वास्तव में भेजा बाहर इस नंबर पर आप इसे भेजने के लिए कहा था की तुलना में कम हो सकती है! देखें, कभी-कभी आप इसे डेटा के पूरे गोब भेजने के लिए बताते हैं और यह इसे संभाल नहीं सकता है। यह जितना डेटा कर सकता है उतना बंद कर देगा, और बाद में को भेजने के लिए आपको भरोसा करेगा। याद रखें, अगर प्रेषण() द्वारा लौटाया गया मान मान में लेन से मेल नहीं खाता है, तो बाकी स्ट्रिंग भेजने के लिए आप पर निर्भर है। अच्छा समाचार यह है: यदि पैकेट छोटा है (1K से कम या तो) यह शायद पूरी चीज को एक ही बार में भेजने का प्रबंधन करेगा। दोबारा, -1 त्रुटि पर लौटा, और errno त्रुटि संख्या पर सेट है।

प्रश्न: क्या "recv()" हमेशा पूरे बफर को पढ़ता है?

ए: नहीं, बिल्कुल नहीं। आपको कभी मानना ​​चाहिए कि आपको प्राप्त बफर "पूरा संदेश" है। या मान लें कि आपको प्राप्त संदेश एक, एकल संदेश से है।

यहां एक अच्छा, संक्षिप्त स्पष्टीकरण है। यह माइक्रोसॉफ्ट/सी # के लिए है, लेकिन यह सब सॉकेट प्रकार लागू होता है मैं/हे, में किसी भी भाषा:

+5

-1: बिल्कुल पीछे की ओर - किसी भी स्ट्रीम आधारित प्रोटोकॉल (जैसे कि टीसीपी) के लिए, प्रेषण अनुरोध की गई राशि से कम वापस आ सकता है, यदि स्थानीय बफर पहले से ही पहले से ही भरा हुआ है। डेटाग्राम प्रोटोकॉल (जैसे यूडीपी) के लिए, प्रेषण या तो असफल हो जाएगा या पूरे बफर को एक पैकेट के रूप में भेज देगा - कोई आंशिक भेजना संभव नहीं है। –

+1

मैंने नीचे मतदान नहीं किया, लेकिन मेरा जवाब देखें, आप गलत हैं। –

+0

@ किरील किरोव - आप और क्रिस डोड बिल्कुल सही के रूप में। माफी माफ करना - माफ करना। मैंने अपना जवाब सही कर दिया है। धन्यवाद! – paulsm4

3

नहीं, ऐसा नहीं है।

संदर्भ के लिए, the man page for send देखें:

संदेश सॉकेट की भेजने बफर में फ़िट नहीं होता है, तो, भेज() सामान्य रूप से ब्लॉक जब तक सॉकेट nonblocking आई/ओ मोड में रखा गया है। गैर-ब्लॉकिंग मोड में यह मामले में त्रुटि EAGAIN या EWOULDBLOCK त्रुटि में विफल हो जाएगा। चुनिंदा (2) कॉल का उपयोग यह निर्धारित करने के लिए किया जा सकता है कि अधिक डेटा भेजना संभव है।

+0

मैनुअल पेज भ्रमित है: टिप्पणी SOCK_STREAM सॉकेट, केवल अन्य प्रकारों पर लागू नहीं होती है। –

4

जवाब man 2 send के दूसरे खंड में है:

When the message does not fit into the send buffer of the socket, 
    send() normally blocks, unless the socket has been placed in nonblock‐ 
    ing I/O mode. In nonblocking mode it would fail with the error EAGAIN 
    or EWOULDBLOCK in this case. The select(2) call may be used to deter‐ 
    mine when it is possible to send more data. 

या, वैकल्पिक रूप से, POSIX संस्करण (man 3p send):

If space is not available at the sending socket to hold the message to 
    be transmitted, and the socket file descriptor does not have O_NONBLOCK 
    set, send() shall block until space is available. If space is not 
    available at the sending socket to hold the message to be transmitted, 
    and the socket file descriptor does have O_NONBLOCK set, send() shall 
    fail. The select() and poll() functions can be used to determine when 
    it is possible to send more data. 

तो, जबकि आंशिक डेटा की एक read आम है , ब्लॉकिंग मोड में आंशिक send नहीं होना चाहिए (कार्यान्वयन विवरण को छोड़कर)।

+0

मैन्युअल पृष्ठ भ्रमित है: टिप्पणी SOCK_STREAM सॉकेट पर लागू नहीं होती है, केवल अन्य प्रकार –

+0

प्रासंगिक कार्य की पॉज़िक्स परिभाषा का एक और हिस्सा है - "यदि संदेश अंतर्निहित प्रोटोकॉल से गुजरने में बहुत लंबा है, तो भेजें () असफल हो जाएंगे और कोई डेटा प्रसारित नहीं किया जाएगा ", यही कारण है कि आप आंशिक रूप से यूडीपी पर नहीं भेजते हैं। –

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