2016-01-27 12 views
7

1) API for send hereResult<usize> देता है। ऐसा क्यों है ? मेरे सिर में, एक यूडीपी भेज सभी या कोई नहीं है।जंग में यूडीपी एपीआई

let mut bytes_written = 0; 
while bytes_written < data.len() { 
    bytes_written += match udp_socket.send_to(&data[bytes_written..]) { 
     Ok(bytes_tx) => bytes_tx, 
     Err(_) => break, 
    } 
} 

हाल ही में किसी ने मुझसे कहा यह पूरी तरह से अनावश्यक है: वापसी मान जो बताते हैं कि भेजने सफल हो लेकिन पूरे डेटा नहीं लिखा जा सकता है जो मुझे कोड की तरह बना देता है लगता है। लेकिन मुझे समझ में नहीं आता है। यदि यह सच था तो बदले में Result<()> क्यों नहीं है, जो भी मैं उम्मीद कर रहा था?

2) For reads हालांकि मैं समझता हूं। मैं इसे आकार 100 बाइट्स का बफर दे सकता हूं लेकिन डेटाग्राम केवल 50 बाइट लंबा हो सकता है। इसलिए अनिवार्य रूप से मुझे केवल read_buf[..size_read] का उपयोग करना चाहिए। यहां मेरा सवाल यह है कि क्या होता है यदि बफर आकार 100 है लेकिन डेटाग्राम आकार 150 बाइट्स कहता है? recv_from केवल 100 बाइट भरें और Ok(100, some_peer_addr) लौटाएं? यदि मैं फिर से पढ़ता हूं तो यह शेष डेटाग्राम भर जाएगा? क्या होगा यदि मेरे दूसरे पढ़ने से पहले 50 बाइट्स का एक और डेटाग्राम आया? क्या मुझे दूसरी बार शेष 50 बाइट्स और तीसरे बार नए डेटाग्राम के 50 बाइट मिलेगा या दूसरी बार 100 बाइट्स मिलेगा जिसमें नया डेटाग्राम भी होगा? या एक त्रुटि होगी और मैं अपने प्रारंभिक पढ़ने पर पहला डेटाग्राम खो दूंगा और कभी भी इसे पुनर्प्राप्त करने में सक्षम नहीं हूं?

उत्तर

9

इन दोनों सवालों का जवाब संबंधित बीएसडी सॉकेट फ़ंक्शन, sendto() और recvfrom() के दस्तावेज़ में निहित है। यदि आप कुछ * निक्स सिस्टम (ओएस एक्स या लिनक्स, उदाहरण के लिए) का उपयोग करते हैं, तो आप इसे खोजने के लिए man sendto और man recvfrom का उपयोग कर सकते हैं।

1) sendto() मैन पेज इस पर अस्पष्ट है; Windows एपीआई पृष्ठ स्पष्ट रूप से कहता है कि वापसी मूल्य len तर्क से कम होना संभव है। this प्रश्न भी देखें। ऐसा लगता है कि यह विशेष क्षण कुछ हद तक कम दस्तावेज है। मुझे लगता है कि यह संभवतः यह मानना ​​सुरक्षित है कि वापसी मूल्य हमेशा len या त्रुटि कोड के बराबर होगा। sendto() के माध्यम से भेजे गए डेटा की लंबाई ओएस कर्नेल के अंदर आंतरिक बफर आकार से अधिक होने पर समस्याएं हो सकती हैं, लेकिन ऐसा लगता है कि कम से कम Windows इस मामले में एक त्रुटि लौटाएंगे।

2) recvfrom() आदमी पेज स्पष्ट रूप से कहा गया है कि एक आंकड़ारेख का हिस्सा है जो बफर में फिट नहीं करता है को छोड़ दिया जाएगा:

recvfrom() फ़ंक्शन संदेश को पत्र लिखा की लंबाई लौटा देगा बफर तर्क द्वारा इंगित बफर। संदेश-आधारित सॉकेट, जैसे SOCK_RAW, SOCK_DGRAM, और SOCK_SEQPACKET के लिए, संपूर्ण संदेश एक ऑपरेशन में पढ़ा जाएगा। यदि एक संदेश आपूर्ति किए गए बफर में फिट होने के लिए बहुत लंबा है, और MSG_PEEK झंडे तर्क में सेट नहीं है, तो अतिरिक्त बाइट को त्याग दिया जाएगा।

तो हाँ, recv_from() ठीक 100 बाइट्स भर जाएगा, बाकी को छोड़ दिया जाएगा, और recv_from() के लिए आगे कॉल नई डाटाग्राम वापस आ जाएगी।

2

यदि आप dig down, तो यह C sendto function को लपेटता है। यह फ़ंक्शन भेजे गए बाइट्स की संख्या देता है, इसलिए जंग बस उस पर गुजरती है (-1 केस को संभालने और गलत त्रुटियों में इरनो को चालू करते समय)।