2012-07-27 14 views
9

मैं ग्राहक पता प्राप्त करने का प्रयास कर रहा हूं, लेकिन मुझे यकीन नहीं है कि मैं सॉकड्रर संरचना को sockaddr_in में कैसे डालूं?आप sockaddr संरचना को sockaddr_in में कैसे डालते हैं - सी ++ नेटवर्किंग सॉकेट्स ubuntu UDP

struct sockaddr_in cliAddr, servAddr; 

    n = recvfrom(sd, msg, MAX_MSG, 0,(struct sockaddr *) cliAddr,sizeof(cliAddr)); 

//i tried this but it does not work 
    struct sockaddr cliSockAddr = (struct sockaddr *) cliAddr; 
    char *ip = inet_ntoa(cliSockAddr.sin_addr); 

अग्रिम धन्यवाद! Getting IPV4 address from a sockaddr structure


भ्रम से बचने के क्षमा करें, यह मेरा असली कार्यान्वयन जहां "ci" स्टोर संकेत करने के लिए एक वस्तु है: :)


मैं सवाल है कि मुझे इस कदम के लिए लाया पाया है जैसे sockaddr_in।

/* receive message */ 
    n = recvfrom(*(ci->getSd()), msg, MAX_MSG, 0,(struct sockaddr *) ci->getCliAddr(),ci->getCliLen()); 

    char *ip = inet_ntoa(ci->getCliAddr().sin_addr); 

मैं मिल जाएगा निम्न त्रुटियों:

udpserv.cpp:166: error: request for member ‘sin_addr’ in ‘ci->clientInfo::getCliAddr()’, which is of non-class type ‘sockaddr_in*’ 
+0

आपका कोड संकलित भी नहीं करेगा। आप एक संरचना के लिए एक सूचक को आवंटित कर रहे हैं, एक सूचक के रूप में 'cliSockAddr' घोषित करें। –

+0

आप जो वास्तव में पूछ रहे हैं वह आपके शीर्षक में जो कहता है उसके विपरीत है। – EJP

उत्तर

13

यह वास्तव में बहुत सरल है!

struct sockaddr *sa = ...; 

if (sa->sa_family == AF_INET) 
{ 
    struct sockaddr_in *sin = (struct sockaddr_in *) sa; 
    ip = inet_ntoa(sin->sin_addr); 
} 
+0

आपको बहुत बहुत धन्यवाद! : डी – mister

+3

और जब आप ऐसा कर रहे हैं, तो AF_INET6 की जांच करके भी अपना प्रोग्राम आईपीवी 6 सक्षम करें। ;) – onitake

2

मुझे लगता है कि यह आपके लिए बस ठीक होगा और आप जो चाहते हैं उसे करें।

struct sockaddr_in cliAddr={}, servAddr={}; 

socklen_t cliAddrLength = sizeof(cliAddr); 

n = recvfrom(sd, msg, MAX_MSG, 0,(struct sockaddr *)&cliAddr, &cliAddrLength); 
18

मैं कहना है कि यह वास्तव में सी ++ करने के लिए इस होगा मुहावरेदार रास्ता है यदि:

sockaddr *sa = ...; // struct not needed in C++ 
char ip[INET6_ADDRSTRLEN] = {0}; 

switch (sa->sa_family) { 
    case AF_INET: { 
    // use of reinterpret_cast preferred to C style cast 
    sockaddr_in *sin = reinterpret_cast<sockaddr_in*>(sa); 
    inet_ntop(AF_INET, &sin->sin_addr, ip, INET6_ADDRSTRLEN); 
    break; 
    } 
    case AF_INET6: { 
    sockaddr_in6 *sin = reinterpret_cast<sockaddr_in6*>(sa); 
    // inet_ntoa should be considered deprecated 
    inet_ntop(AF_INET6, &sin->sin6_addr, ip, INET6_ADDRSTRLEN); 
    break; 
    } 
    default: 
    abort(); 
} 

यह नमूना कोड IPv4 और IPv6 पतों संभालती है और यह भी अधिक सी ++ से मुहावरेदार पर विचार किया जाएगा सुझाए गए कार्यान्वयन में से कोई भी।

+0

मुझे वाकई यह पसंद है कि आपने reinterpret_cast का उपयोग किया है। यह सब कुछ इतना साफ बनाता है, और कम पॉइंटर्स का उपयोग करने की आवश्यकता है। एक तरफ ध्यान दें, मैंने शुरुआत करने के लिए एक सूचक के रूप में सेट नहीं किया था। मैंने बस इस तरह के संदर्भ में इस पते को पारित किया है (मेरा एक स्कूल प्रोजेक्ट है और केवल आईपीवी 4 - inet_ntoa (reinterpret_cast (और clientIpAddress) -> sin_addr का उपयोग कर) – adpro