2010-06-17 15 views
24

मैं सरल सर्वर/क्लाइंट लिख रहा हूं और क्लाइंट आईपी एड्रेस प्राप्त करने की कोशिश कर रहा हूं और यह तय करने के लिए सर्वर क्लाइंट को सहेज रहा हूं कि कौन सा क्लाइंट महत्वपूर्ण अनुभाग में आना चाहिए। मैंने इसे कई बार गुगल किया लेकिन सॉक संरचना से आईपी पता पाने का उचित तरीका नहीं मिला।सी में एसॉक संरचना से आईपी पता कैसे प्राप्त करें?

मेरा मानना ​​है कि ग्राहक क्लाइंट से अनुरोध स्वीकार करने के बाद आईपी प्राप्त करने का एक तरीका है। अधिक विशेष रूप से सी सर्वर के बाद में निष्पादित

csock = accept(ssock, (struct sockaddr *)&client_addr, &clen) 

धन्यवाद

+0

बस सभी को यह बताएं कि चेक किए गए उत्तर कई मायने रखता है। कृपया, कृपया, अन्य सभी प्रोग्रामर के अच्छे के लिए, इसका उपयोग न करें। – Omnifarious

उत्तर

36

ठीक आप यह सोचते हैं IPV4 तो निम्नलिखित करें उपयोग कर रहे हैं:

struct sockaddr_in* pV4Addr = (struct sockaddr_in*)&client_addr; 
struct in_addr ipAddr = pV4Addr->sin_addr; 

आप तो एक स्ट्रिंग के रूप ip पता चाहते हैं तो ऐसा निम्नलिखित:

char str[INET_ADDRSTRLEN]; 
inet_ntop(AF_INET, &ipAddr, str, INET_ADDRSTRLEN); 

IPV6 के साथ-साथ बहुत आसान है ...

struct sockaddr_in6* pV6Addr = (struct sockaddr_in6*)&client_addr; 
struct in6_addr ipAddr  = pV6Addr->sin6_addr; 

और एक स्ट्रिंग हो रही IPV4

char str[INET6_ADDRSTRLEN]; 
inet_ntop(AF_INET6, &ipAddr, str, INET6_ADDRSTRLEN); 
+2

आप 'str' बफर को 'inet_ntop()' में पास करना भूल गए हैं। और 'sin_addr' एक संरचना है - किसी को' sin_addr.s_addr' का उपयोग करना होगा। यह ध्यान देने योग्य है कि आईपीवी 4 पता नेटवर्क बाइट ऑर्डर में संग्रहीत है और इसे हेक्स नंबर के रूप में देखने के लिए 'ntohl (pV4Addr-> sin_addr.s_addr)' का उपयोग करने की आवश्यकता होगी। – Dummy00001

+0

अंक उठाए गए ... आपने लोअरकेस "इन 6_addr" का उपयोग न करने से भी मुझे याद किया;) एनओटीएच फ्रंट पर मैं अक्सर परेशान नहीं होता क्योंकि मैं अभी भी समानता जांच कर सकता हूं (दोनों नेटवर्क ऑर्डर में हैं) और यह inet_ntop को तोड़ देगा (है ना?)। – Goz

+2

यह प्रश्न टैग किया गया है सी - आप 'struct sockaddr_in *' जैसे प्रकारों में 'struct' को नहीं छोड़ सकते हैं। साथ ही, IPV4 विधि को आपके द्वारा दिखाए गए आईपीवी 6 विधि के समान, पते को स्टोर करने के लिए 'int' के बजाय' struct in_addr' का उपयोग करना चाहिए। – caf

21

client_addr मान लिया जाये कि लगभग समान है (जो यह आम तौर पर है) एक struct sockaddr_in है। आप client_addr.sin_addr.s_addr से आईपी पता (32-बिट हस्ताक्षरित पूर्णांक के रूप में) प्राप्त कर सकते हैं।

आप इसे एक स्ट्रिंग के लिए इस तरह से परिवर्तित कर सकते हैं:

printf("%d.%d.%d.%d\n", 
    int(client.sin_addr.s_addr&0xFF), 
    int((client.sin_addr.s_addr&0xFF00)>>8), 
    int((client.sin_addr.s_addr&0xFF0000)>>16), 
    int((client.sin_addr.s_addr&0xFF000000)>>24)); 
+27

आपको बिट्स के साथ मैन्युअल रूप से झुकाव के बजाय inet_ntoa() का उपयोग करना चाहिए। –

+12

'inet_ntoa' थ्रेड-सुरक्षित नहीं है, हालांकि यह उन मामलों के लिए महत्वपूर्ण नहीं हो सकता है जहां इसका उपयोग किया जाता है। एक सुरक्षित विकल्प 'inet_ntop' है। – jweyrich

+3

यह किसी भी बड़े एंडियन वास्तुकला के लिए काम नहीं करेगा। – Ternvein

26

आईपी पते और पोर्ट संख्या निकालने के लिए आसान और सही तरीका होगा:

printf("IP address is: %s\n", inet_ntoa(client_addr.sin_addr)); 
printf("port is: %d\n", (int) ntohs(client_addr.sin_port)); 

सोपबॉक्स के स्वीकार किए जाते हैं जवाब नहीं होगा सभी आर्किटेक्चर के लिए सही हो। Big and Little Endian देखें।

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