2009-05-31 24 views
8

ठीक है सबसे पहले मैं यह उल्लेख करना चाहता हूं कि मैं क्या कर रहा हूं पूरी तरह से नैतिक है और हाँ मैं पोर्ट स्कैनिंग कर रहा हूं।सी ++ लिनक्स में सॉकेट टाइमआउट

पोर्ट बंद होने पर प्रोग्राम ठीक चलाता है लेकिन जब मैं एक बंद सॉकेट पर जाता हूं तो प्रोग्राम बहुत लंबे समय तक रुक जाता है क्योंकि कोई टाइम-आउट क्लॉज नहीं होता है। नीचे निम्न कोड

int main(){ 

    int err, net; 
    struct hostent *host; 
    struct sockaddr_in sa; 

    sa.sin_family = AF_INET; 

    sa.sin_port = htons(xxxx); 
    sa.sin_addr.s_addr = inet_addr("xxx.xxx.xxx.xxx"); 

    net = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 
    err = connect(net, (struct sockaddr *)&sa, sizeof(sa)); 

    if(err >= 0){ cout << "Port is Open"; } 
    else { cout << "Port is Closed"; } 

} 

मैं ढेर अतिप्रवाह पर इस पाया है लेकिन यह सिर्फ एक select() आदेश का उपयोग मेरे लिए कोई मतलब नहीं है।

प्रश्न क्या हम कनेक्ट() फ़ंक्शन टाइमआउट कर सकते हैं ताकि हम एक त्रुटि के साथ वापस आने के लिए एक वर्ष का इंतजार न करें?

+14

कोई ज़रूरत नहीं के लिए एक लिंक है - यह बैंक और हर बार बताता है कि आपके पैसे निकालने के लिए और इसे लूटने के लिए नहीं चाहते के लिए दिशानिर्देश पूछकर की तरह है .. – stefanB

+1

: डी अच्छी तरह से डाल दिया। लेकिन मैं पैसे वापस नहीं ले रहा हूं: डी –

उत्तर

7

सबसे आसान सेटअप करने के लिए है एक alarm और connect एक संकेत के साथ बाधित हो गए हैं (UNP 14.2 देखें):


signal(SIGALRM, connect_alarm); /* connect_alarm is you signal handler */ 
alarm(secs); /* secs is your timeout in seconds */ 
if (connect(fs, addr, addrlen) < 0) 
{ 
    if (errno == EINTR) /* timeout */ 
     ... 
} 
alarm(0); /* cancel alarm */ 

हालांकि select का उपयोग कर बहुत कठिन नहीं है :)
आप के बारे में जानने के लिए चाहते हो सकता है raw sockets भी।

+1

धन्यवाद, यह काम करता है कि मुझे अलार्म और सिग्नल चीज को समझना था कि यह कैसे काम करता है लेकिन कोई भी कम नहीं, यह मैंने टिन पर पूछा है। धन्यवाद: डी –

+0

'सिग्नेक्शन' को आम तौर पर 'सिग्नल' के लिए प्राथमिकता दी जानी चाहिए, जिसमें अलग-अलग यूनिक्स पर अलग-अलग व्यवहार हैं। – ephemient

+0

यह सच है, कोड सीधे स्टीवंस से उद्धृत किया गया था। –

2

यदि आप इसे करने के लिए अवरुद्ध आईओ का उपयोग करने पर मृत सेट हैं, तो आपको सेटॉकॉप() कॉल, विशेष रूप से SO_SNDTIMEO ध्वज (या आपके ओएस के आधार पर अन्य झंडे) की जांच करनी चाहिए।

सावधान रहें कि ये झंडे विश्वसनीय/पोर्टेबल नहीं हैं और किसी दिए गए प्लेटफ़ॉर्म के विभिन्न प्लेटफ़ॉर्म या विभिन्न संस्करणों पर अलग-अलग कार्यान्वित किए जा सकते हैं।

ऐसा करने का पारंपरिक/सबसे अच्छा तरीका अनब्लॉकिंग दृष्टिकोण के माध्यम से है जो चुनिंदा() का उपयोग करता है। यदि आप सॉकेट के लिए नए हैं, तो सबसे अच्छी किताबों में से एक टीसीपी/आईपी इलस्ट्रेटेड, वॉल्यूम 1: प्रोटोकॉल है। यह कम से अमेज़न पर है: http://www.amazon.com/TCP-Illustrated-Protocols-Addison-Wesley-Professional/dp/0201633469

+0

SO_SNDTIMEO कनेक्ट() पर काम नहीं करेगा – ernesto

1

RudeSocket हल समस्या

मुझे लगता है कि लिनक्स फेडोरा में परीक्षण किया जाता है एक lib फ़ाइल (विंडोज बारे में निश्चित नहीं) में पाया गया है कि मुझे समय समाप्ति का विकल्प देता है। नीचे आप एक बहुत ही सरल उदाहरण पा सकते हैं।

#include <rude/socket.h> 
#include <iostream> 

using namespace std; 
using namespace rude; 

Socket soc; 
soc.setTimeout(30, 5); 

//Try connecting 
if (soc.connect("xxx.xxx.xxx.xxx", 80)){ 

    cout << "Connected to xxx.xxx.xxx.xxx on Port " << 80 << "\n"; 
} 

//connections Failed 
else{ 
    cout << "Timeout to xxx.xxx.xxx.xxx on Port " << 80 << "\n"; 
} 

soc.close(); 

यहाँ समझाने के लिए कारण है कि आप इसकी आवश्यकता DevSite

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