2012-01-10 11 views
6

के तहत सी में "अनुरोधित पता असाइन नहीं किया जा सकता" जब मैं यह पता असाइन करता हूं, तो यह cannot assign requested address कहता है। लेकिन जब मैं स्थानीय पता डालता हूं (127.0.0.1) यह इसे स्वीकार करता है। क्यूं कर???मुझे रन टाइम में त्रुटि मिली है कि लिनक्स (Centos)

char* hostname = "192.168.1.8"; 

int sockfd; 
struct sockaddr_in my_addr; // my address information 
struct sockaddr_in their_addr; // connector's address information 
socklen_t addr_len; 
int numbytes; 
char buf[MAXBUFLEN]; 
int port =5000; 

if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { 
    perror("socket"); 
    exit(1); 
} 
try 
{ 
    my_addr.sin_family = AF_INET;  // host byte order 
    my_addr.sin_addr.s_addr = inet_addr(hostname); 

    printf("Accepted/n"); 
    // automatically fill with my IP 
    my_addr.sin_port = htons(5000); // short, network byte order 
    memset(&(my_addr.sin_zero), '\0', 8); // zero the rest of the struct 

    if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) 
    { 
     perror("bind"); 
     exit(1); 
    } 
    while (1) 
    { 
     addr_len = sizeof(struct sockaddr); 
     if ((numbytes = recvfrom(sockfd, buf, MAXBUFLEN-1 , 0, 
      (struct sockaddr *)&their_addr, &addr_len)) == -1) { 
      perror("recvfrom"); 
      exit(1); 
     } 

     //printf("got packet from %s\n",inet_ntoa(their_addr.sin_addr)); 
     //printf("packet is %d bytes long\n",numbytes); 
     buf[numbytes] = '\0'; 
     //printf("packet contains \"%s\"\n",buf); 
    } 

    close(sockfd); 
} 
catch(...) 
{ 
+3

शायद क्योंकि आपकी मशीन का स्थानीय पता 192.168.1.8 नहीं है? –

+2

इसके अलावा, आपने इसे सी के रूप में टैग किया है लेकिन मुझे 'try {...} catch (...) {...} 'ब्लॉक दिखाई देता है। क्या यह सी ++ होना चाहिए? –

उत्तर

11

तो त्रुटि bind पर हो रहा है (यह त्रुटि संदेश आप राज्य कोड में प्रकट नहीं होता के बाद से अपने प्रश्न सामग्री के आधार पर स्पष्ट नहीं है), यह होने की संभावना है क्योंकि पता उपलब्ध नहीं है।

आमतौर पर यह इसलिए है क्योंकि यह पहले से ही उपयोग में है, या वर्तमान होस्ट पर उपलब्ध नहीं है।

कुछ अपवादों के साथ, आप आम तौर पर केवल अपने स्थानीय इंटरफेस को आवंटित आईपी पते से जोड़ सकते हैं। आपको उस वर्ग में 192.168.1.8 जांचना चाहिए। यह एक दिया गया है कि 127.0.0.1 एक स्थानीय इंटरफ़ेस होगा (इसलिए यह क्यों काम करता है), और INADDR_ANY भी काम करेगा - शायद यह "पता" है जिसका उपयोग तब तक करना चाहिए जब तक कि आपके पास एक इंटरफ़ेस तक सीमित होने की वास्तविक विशिष्ट आवश्यकता न हो।

असफल कार्य के बाद आपको errno की जांच करनी चाहिए और possibilities के विरुद्ध मेल खाना चाहिए।


एक अलग रूप में के रूप में, और यह शायद आपकी समस्या के लिए अप्रासंगिक है, जिस तरह आप आरंभ sockaddr_in संरचना (स्थापित करने के खेतों फिर बाकी समाशोधन) मेरे लिए पोर्टेबल की तुलना में कम हो रहा है।

मुझे लगता है कि यह बहुत स्पष्ट करने के लिए तो बस आप उस के बाद क्या इच्छा सेट सुरक्षित हो सकता है, कुछ की तरह:

memset (&my_addr, 0, sizeof (my_addr)); 
my_addr.sin_family  = AF_INET; 
my_addr.sin_addr.s_addr = inet_addr (hostname); 
my_addr.sin_port  = htons (5000); 

कम से कम इस तरह, ढांचे के भीतर क्षेत्रों के क्रम को प्रभावित नहीं करेगा आपके कोड।


आप निम्न कोड के साथ समस्या देख सकते हैं। सबसे पहले, अपेक्षित शीर्षलेख:

#define __USE_GNU 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 

फिर तर्क जांच और सॉकेट निर्माण।

int main (int argc, char *argv[]) { 
    int sockfd; 
    struct sockaddr_in me; 

    if (argc < 2) { 
     printf ("Need argument with IP address\n"); 
     return 1; 
    } 

    if ((sockfd = socket (AF_INET, SOCK_DGRAM, 0)) == -1) { 
     perror("socket"); 
     return 1; 
    } 

तब ही बाध्यकारी:

memset (&me, 0, sizeof (me)); 
    me.sin_family = AF_INET; 
    me.sin_addr.s_addr = inet_addr (argv[1]); 
    me.sin_port = htons (5000); 

    if (bind (sockfd, (struct sockaddr *)&me, sizeof(struct sockaddr)) == -1) 
    { 
     fprintf (stderr, "errno = %d ", errno); 
     perror("bind"); 
     exit(1); 
    } 

    close(sockfd); 

    return 0; 
} 

जब आप चलने वाले कुछ तर्क के साथ, आप इसे हैं जहां आईपी पतों के स्थानीय इंटरफेस (127.0.0.1 और 192.168.0.101) से संबंध रखते हैं के लिए ठीक काम करता है देख सकते हैं लेकिन नहीं उन है कि नहीं करते हैं, 192.168.0.102 तरह के लिए: bind आदमी पृष्ठ पर ऊपर

pax> ifconfig | grep 'inet addr' 
     inet addr:192.168.0.101 Bcast:192.168.0.255 Mask:255.255.255.0 
     inet addr:127.0.0.1       Mask:255.0.0.0 
     inet addr:192.168.99.1 Bcast:192.168.99.255 Mask:255.255.255.0 
     inet addr:192.168.72.1 Bcast:192.168.72.255 Mask:255.255.255.0 

pax> ./testprog 127.0.0.1 

pax> ./testprog 192.168.0.101 

pax> ./testprog 192.168.0.102 
errno = 99 bind: Cannot assign requested address 

pax> grep '#define.*99' /usr/include/asm-generic/errno.h 
#define  EADDRNOTAVAIL  99  /* Cannot assign requested address */ 

और, लिंक से, हम देखें:

EADDRNOTAVAIL
              एक अस्तित्वहीन इंटरफ़ेस अनुरोध किया गया था या अनुरोध किया पते स्थानीय नहीं था।

+0

यह एक बहुत ही विस्तृत कोड समीक्षा है – bn00d

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