2010-11-15 11 views
5

मैं a clone of inetd लिख रहा हूं जिसमें मुझे एक सर्वर चलाया जाना चाहिए जो क्लाइंट के आईपी और पोर्ट को प्रिंट करता है।सॉकेट डिस्क्रिप्टर से आईपी/पोर्ट को पुनर्प्राप्त करना

मैं STDIN और STDOUT के ऊपर लिख के रूप में सॉकेट वर्णनकर्ता के साथ, my initial solution यह करने के लिए sockaddr_in संरचना है, जो जरूरत में जानकारी शामिल है ठीक करने के लिए किया गया था। getsockname() के साथ ऐसा करने से, एक खाली संरचना वापस आ रही है, सभी बिट्स 0

मेरे दृष्टिकोण के साथ क्या गलत है इसका कोई विचार? क्या आईपी/पोर्ट को पुनर्प्राप्त करने के लिए मैं कोई अन्य दृष्टिकोण उपयोग कर सकता हूं?

धन्यवाद

उत्तर

8

आर के रूप में .. इंगित किया गया है, आपको getpeername का उपयोग करना चाहिए। दोनों फ़ंक्शन और getsockname फ़ाइल डिस्क्रिप्टर को अपना पहला तर्क के रूप में लें, न कि स्ट्रीम पॉइंटर (FILE *)। मानक इनपुट के लिए फ़ाइल डिस्क्रिप्टर प्राप्त करने के लिए fileno(stdin) का उपयोग करें (या हार्ड-कोड इसे STDIN_FILENO पर रखें, क्योंकि यह स्थिर है)।

इसके अलावा, getsockname और getpeername को अंतिम तर्क socklen_t के लिए सूचक, एक निरंतर नहीं होना चाहिए, और आप टीसीपी/आईपी के लिए एक sockaddr_in उपयोग करना चाहिए:

struct sockaddr_in peeraddr; 
socklen_t peeraddrlen = sizeof(peeraddr); 
getpeername(STDIN_FILENO, &peeraddr, &peeraddrlen); 

पूर्ण उदाहरण here देखें।

+0

ओपी ने सॉकेट के लिए फाइल डिस्क्रिप्टर के साथ "अधिलेखित" stdin और stdout का उल्लेख किया है, जिसे अनुचित रूप से सबसे अच्छा शब्द दिया जाता है, लेकिन यह संकेत दे सकता है कि प्रतिस्थापन गलत तरीके से किया जा रहा है और stdin (fd 0) वास्तव में एक सॉकेट नहीं है ... –

+0

@ आर .., https://github.com/konr/Licio/blob/master/05/time पर अपना कोड देखें।सी –

+1

डुनो अगर यह * समस्या है, लेकिन 'शून्य * * के लिए वास्तव में बदसूरत विकल्प के अलावा' स्ट्रक्चर सॉकडर 'का उपयोग करना हमेशा एक गलती है। आपके पास 'struct sockaddr' प्रकार की वास्तविक वस्तुएं नहीं होनी चाहिए। हमेशा आवश्यकतानुसार 'struct sockaddr_in',' struct sockaddr_in6', या 'struct sockadd_storage' का उपयोग करें। –

3

उपयोग getpeername। मुझे संदेह है कि आपकी समस्या यह है कि getsockname सॉकेट के अपने (स्थानीय) पक्ष के लिए जानकारी लौटा रहा है, जो शायद 0.0.0.0 (जिसका अर्थ है कि यह किसी भी इंटरफ़ेस से कनेक्शन स्वीकार कर सकता है) से जुड़ा हुआ है।

संपादित करें: मुझे लगता है कि मुझे आपकी वास्तविक बग कोड पढ़ने में मिली है। इस लाइन गलत है:

getsockname(stdin, &addr, sizeof(addr)); 

getsockname और getpeername कार्यों एक socklen_t * उनके तीसरा तर्क है, न कि size_t के रूप में (एक सूचक) ले लो। कंपाइलर आपको इस गलती के बारे में बताना चाहिए जबतक कि आप getsockname के प्रोटोटाइप के साथ हेडर शामिल करना भूल गए। इसके अलावा, जैसा कि पहले से ही कहा जा चुका है, stdin गलत है। प्रयास करें:

socklen_t len = sizeof addr; 
getpeername(0, &addr, &len); 

या (C99 केवल):

getpeername(0, &addr, (socklen_t[1]){sizeof addr}); 

तुम भी वापसी मान की जाँच की जानी चाहिए; यदि आपने किया, तो आप देखेंगे कि यह त्रुटियों की वापसी कर रहा है।

+0

कोई उपयोग नहीं, परिणाम अभी भी 0. – konr

+2

यदि आपका मतलब है कि getpeername() 0 देता है, तो इसका मतलब है कि फ़ंक्शन सफल रहा है। – Simone

2

यदि आपको रिमोट क्लाइंट के लिए उन जानकारी की आवश्यकता है, तो आपको getpeername() पर कॉल करना होगा।

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