2011-10-09 12 views
7

मैं XML-LibXSLT मॉड्यूल के मेंटेनर और परीक्षणों में से एक एक गैर-मौजूद URL तक पहुंच की आवश्यकता है (तो वहाँ एक गैर उपलब्ध URL हो जाएगा)। समस्या यह थी कि किसी ने बताया कि उनके सिस्टम पर यूआरएल मौजूद था, इसलिए मैंने स्थानीयहोस्ट पर एक यादृच्छिक बंदरगाह आवंटित करने का फैसला किया जहां मुझे यकीन है कि कोई वेब-सेवा नहीं होगी। ऐसा किया गया था:पर्ल: कैसे portably एक TCP पोर्ट आरक्षण

# We reserve a random port to make sure the localhost address is not 
# valid. See: 
# 
# https://rt.cpan.org/Ticket/Display.html?id=52422 

my $sock = IO::Socket::INET->new(
    Proto => 'tcp', 
); 

my $port = $sock->sockport(); 

$file = "http://localhost:${port}/allow.xml"; 

अब, समस्या यह है कि $ बंदरगाह परिभाषित किया गया है और वैध लिनक्स पर (एक आरक्षित बंदरगाह के मूल्य के) है, लेकिन यह विंडोज पर काम करने के लिए प्रकट नहीं होता है - इस बग को देखने के रिपोर्ट - https://rt.cpan.org/Ticket/Display.html?id=71456। मेरा सवाल है: मैं पर्ल 5 में यूनिक्स, मैक ओएस एक्स और विंडोज़ में पोर्टेबल रूप से एक नया, यादृच्छिक, अभी तक कब्जा कर लिया बंदरगाह कैसे आरक्षित कर सकता हूं?

सादर,

Shlomi मछली

उत्तर

5

आपको पोर्ट 0 का उपयोग कर लूपबैक पता (कि इतने एक बंदरगाह आप के लिए आवंटित किया जाएगा) को bind में सक्षम होना चाहिए। बोनस प्वाइंट्स के लिए आप connect सॉकेट को स्वयं (शायद कहीं भी आवश्यक नहीं है, लेकिन इसकी गारंटी देनी चाहिए कि उसे पता है)

+0

+1। कनेक्ट() अनावश्यक है। – EJP

+0

@EJP: सच है, मैं बेहद कमजोर याद करता हूं कि पोर्ट बंदरगाह आवंटन के लिए कुछ हद तक आलसी दृष्टिकोण ले रहा है, कम से कम 'INADDR_ANY' बाउंड सॉकेट के लिए। – Hasturkun

+0

बंदरगाह() समय पर बंदरगाह आवंटित किया गया है। – EJP

0

मुझे लगता है (लेकिन यहां से साबित नहीं कर सकते) विंडोज पर कि पोर्ट संख्या वास्तव में इस तरह समय के रूप में सॉकेट वास्तव में सुन रहा शुरू होता है जब तक आवंटित नहीं किया गया है।

हालांकि होने सॉकेट वास्तव में के रूप में तेजी से के रूप में यह बाद से प्रारंभिक TCP कनेक्शन वास्तव में कामयाब होने की हो सकती है नाकाम रहने से परीक्षण नहीं कर पाएगा सुनने।

तुम सिर्फ test.example.com बजाय इस पर URL है, जो अस्तित्व में नहीं की गारंटी है ओर इशारा करते हुए विचार किया है?

+0

[http://example.com] (http://example.com) है - यह पंजीकृत नहीं किया जा सकता है, लेकिन यह मौजूद है। –

+0

मैं यहां एक इंटरनेटवर्क संसाधन का उपयोग नहीं करना चाहूंगा क्योंकि बाहरी नेटवर्क उपलब्ध नहीं हो सकता है और क्योंकि मैं नहीं चाहता कि परीक्षण उपयोगकर्ता के अनुबंध के बिना कहीं "फोन" करें। –

+0

@ e.dan यही कारण है कि मैंने एक सबडोमेन – Alnitak

4

आप bind सॉकेट + पते पर सॉकेट चाहते हैं। ऐसा होगा यदि आप LocalAddr (या LocalHost) निर्दिष्ट करते हैं। यदि आप पोर्ट निर्दिष्ट नहीं करते हैं (या आप पोर्ट शून्य निर्दिष्ट करते हैं), तो आपके लिए एक निःशुल्क पोर्ट चुना जाएगा।

use strict; 
use warnings; 
use 5.010; 

use IO::Socket::INET qw(INADDR_ANY); 

my $sock = IO::Socket::INET->new(
    Proto  => 'tcp', 
    LocalAddr => INADDR_ANY, 
); 

my $port = $sock->sockport(); 

say $port; # 60110 

मुझे लगता है कि आप केवल लूपबैक एडाप्टर से कनेक्शन स्वीकार करना चाहते हैं। यदि ऐसा है, तो INADDR_ANY के बजाय INADDR_LOOPBACK का उपयोग करें।

1

इस छोटे से उपकरण https://github.com/yegor256/random-tcp-port (मैं एक डेवलपर हूँ) की कोशिश करो। Windows में काम करना चाहिए, क्योंकि यह एएनएसआई सी

+0

जो एएनएसआई सी नहीं है, सी नेटवर्किंग एपीआई नहीं है, मुझे पॉज़िक्स दिखाई देता है –

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