2014-05-12 20 views
13

इस कोड को अंतिम पंक्तिIPAddress.MapToIPv4() क्यों ArgumentOutOfRangeException फेंक देता है?

var initAddress = IPAddress.Parse("1.65.128.190"); 
var ipv6Address = initAddress.MapToIPv6(); 
Assert.IsTrue(ipv6Address.IsIPv4MappedToIPv6); 
var ipv4Address = ipv6Address.MapToIPv4(); 

पर एक ArgumentOutOfRangeException फेंकता है किसी को भी व्याख्या कर सकते हैं क्यों MapToIPv6() और MapToIPv4() राउंड ट्रिप संगत नहीं हैं?

संपादित करें: अपवाद आईपीएड्रेस कन्स्ट्रक्टर से निकलता है, जिसे MapToIPv4() द्वारा बुलाया जाता है।

इसके अलावा

, जब पहली पंक्ति

var initAddress = IPAddress.Parse("1.65.128.90"); 

कोई अपवाद नहीं फेंक दिया जाता है अब और

EDIT2 है: के रूप में @Luaan इस reproduced, मैं टैग [बग रिपोर्टिंग] को शामिल किया। [बीसीएल] भी जोड़ा। चलो देखते हैं किसी भी एमएस कर्मियों उन टैग :)

edit3 पटरियों यदि: कनेक्ट https://connect.microsoft.com/VisualStudio/feedback/details/871964 पर सूचना दी

+0

दिलचस्प। बहुत सारे आईपीवी 4 पते हैं जिनके लिए यह ठीक काम करता है। असल में, कुछ विज्ञापन-परीक्षण परीक्षणों के आधार पर, ऐसा लगता है कि आखिरी बिट दोष देना है - शायद कोड में कहीं भी एक त्रुटि है जो उदारतापूर्वक 'लंबी', 'उलंग' और' int' का उपयोग सकारात्मक और नकारात्मक संख्याओं के साथ करती है । आप आईपीवी 6 मैप किए गए आईपीवी 4 पते क्यों चाहते हैं, यद्यपि? क्या आप लिनक्स सर्वर के साथ काम कर रहे हैं? मैंने सोचा कि विंडोज वास्तव में उनको संभाल नहीं लेता है (क्योंकि आईपीवी 4 और आईपीवी 6 नेटवर्किंग स्टैक पर अलग-अलग ड्राइवर हैं - आपको आईपीवी 4 और आईपीवी 6 दोनों को संभालने के लिए दो अलग सॉकेट की आवश्यकता है)। – Luaan

+0

ठीक है, मुझे वास्तव में इसकी आवश्यकता नहीं है, लेकिन पते की तुलना करते समय मैंने इसे एक छोटी सी जीत माना। मुझे लगता है कि मैं भाग्यशाली हूं कि मेरे कोड के परीक्षणों में वास्तव में मुझे इस तरह का पता था, मुझे अपने समय से पहले (असुरक्षित) अनुकूलन से दूर ले जाने के लिए ... –

+0

@ पैट्रिकहुइजिंग आह, मैं भी बग रिपोर्ट पोस्ट कर रहा हूं। वैसे भी, मैंने तुम्हारा ऊपर उठाया :) – Luaan

उत्तर

17

ठीक है, मैं वास्तव में इस की पुष्टि कर लें, तो मुझे एक जवाब के रूप में पोस्ट करते हैं।

IPAddress कक्षा में आईपीवी 4 पर पते मैप करते समय एक त्रुटि है। संख्या सभी int रों हैं -

long address = 
    (((m_Numbers[6] & 0x0000FF00) >> 8) | ((m_Numbers[6] & 0x000000FF) << 8)) | 
    ((((m_Numbers[7] & 0x0000FF00) >> 8) | ((m_Numbers[7] & 0x000000FF) << 8)) << 16); 

समस्या .NET में बिटवाइज़ संचालन कर रही है किसी को भी काफी स्पष्ट होना चाहिए:

नेट संदर्भ कोड के अनुसार, यह करता है। तो दूसरे ushort (m_Numbers[7]) को स्थानांतरित करना नकारात्मक मान देगा, क्योंकि सबसे महत्वपूर्ण बिट 1 है। इसका अर्थ यह है कि 127 से अधिक बाइट के साथ समाप्त होने वाले सभी आईपीवी 4 पते आईपीवी 6 से वापस मैप करते समय त्रुटि उत्पन्न करेंगे।

उन्हें आसानी से ठीक इस होगा:

long address = 
(((m_Numbers[6] & 0x0000FF00) >> 8) | ((m_Numbers[6] & 0x000000FF) << 8)) 
| 
(
    (uint)(((m_Numbers[7] & 0x0000FF00) >> 8) | ((m_Numbers[7] & 0x000000FF) << 8)) 
    << 16 
); 

बस एक uint को int कास्टिंग bitshift चाल है करने से पहले से।

जब आप हस्ताक्षरित प्रकारों में कारक होते हैं तो बिटवाई ऑपरेशंस काफी मुश्किल हो सकता है। मुझे लगता है कि कोड को सी ++ लाइब्रेरी या कुछ से कॉपी किया गया था, जहां यह समस्या प्रकट नहीं होगी।

+1

क्या आप यह कह रहे हैं कि यह अनिवार्य रूप से .NET स्रोत में एक बग है? - क्या माइक्रोसॉफ्ट को इसकी सूचना दी जानी चाहिए? – series0ne

+5

@ series0ne Yup, अब इसकी सूचना दी गई है - https://connect.microsoft।com/VisualStudio/फीडबैक/विवरण/871 9 64/ipaddress-maptoipv4-throws-argumentoutofrangeexception – Luaan

+1

बस हर किसी के संदर्भ के लिए, मैंने इसे पूरी तरह से पैच किए गए सर्वर पर .NET Framework 4.5.2 चलाया, इसलिए मुझे लगता है कि फिक्स 4.6 तक नहीं होगा –

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