2013-01-21 3 views
1

sockaddr 구조를 직접 채우지 않고 수동 소켓/수신기와 함께 getaddrinfo 함수를 사용하려고합니다. 내 목적은 소켓을 열고 포트에 바인딩하는 것입니다. 본질적으로 저는 서버를 만들고 있습니다.getaddrinfo는 localhost를 사용하여 2 개의 결과를 반환합니다.

왜 그런지 모르겠지만 getaddrinfo은 (는) 검색 결과 2 개를 반환합니다. 이 때문에 두 번째 아래의 루프에서 바인드를 호출하면 "주소가 이미 사용 중입니다"라는 오류 메시지가 나타납니다. 이 문제를 해결하는 방법을 알고 있으며 반복적으로 처리하는 것이 맞습니까?

  struct addrinfo addr; 
     memset(&addr,0,sizeof(addrinfo)); 
     addr.ai_family = AF_INET; 
     addr.ai_socktype = SOCK_STREAM; 
     addr.ai_protocol = 0; 
     addr.ai_flags = AI_PASSIVE; 

     struct addrinfo * rp,* result; 
     getaddrinfo("localhost","59001",&addr,&result); 
     for(rp = result; rp != NULL; rp = rp->ai_next){ 

       int sd = socket(AF_INET, SOCK_STREAM, 0); 
       if(-1==sd){ 
       printf("error creating the socket %m"); 
       return -1; 
       }    

      if(-1==bind(sd, result->ai_addr, result->ai_addrlen)){     
      printf("error binding %m") 
      return -1; 
      } 

      if(-1== listen(sd, MAX_BACKLOG)){ 
      std::cerr << "listen didn't work" << std::endl; 
      return -1; 
      }  
     } 
+0

음을 참조 맨 페이지는 말한다 : "하나 개 이상되는 addrinfo 구조를 반환합니다." 두 가지 결과 중 올바른 것을 골라야합니다. –

+0

감사합니다. 이것은 고쳐지고 내 일을 끝내게됩니다! –

답변

4

여기에 몇 가지가 있습니다. getaddrinfo()의 여러 결과는 IPv4 주소와 IPv6 주소 (둘 다 가지고 있음)를 반환하기 때문입니다. "이미 사용중인 주소"에 대해서는 SO_REUSEADDR 옵션을 설정해야합니다. socket()bind()로 통화 사이의이 넣어 :

int opval = 1; 
setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)); 
+0

안녕하십니까. 당신 말이 맞고 작동합니다. 것은 (나는 지금 깨달았다). 내가 전화해야한다는 것도 들어요. 일단 내가 듣고 전화를 사용하면 주소가 사용되며 그 오류가 발생했습니다. 이 경우 2 가지 결과 중 어느 것을 폐기해야합니까 (해야만한다면?). –

+2

@AbruzzoForteeGentile : 소켓을 성공적으로 생성 한 첫 번째 소켓을 사용해야합니다. – Linuxios

+0

확인. 나는 그것을 할 것이다. IPV4 또는 IPV6 임에도 불구하고 (그리고 나는 그 차이가 무엇인지 이해할 것이다.) 고마워요! –

0

이는 레드햇 기계 우연히 켜져 있습니까? 그들에게 잘 알려진 버그가 있습니다. 왜냐하면 /etc/hosts/localhost을 두 번 나열하기 때문에, 특별히 AF_INET을 요청하면 실제로 두 번 같은 결과가 나타납니다. IPv4 용으로 한 번, IPv6 용으로 한 번 번역되었습니다.

https://bugzilla.redhat.com/show_bug.cgi?id=496300

+0

안녕하세요. 나는 우분투에서이 코드를 시도하고있다. –

관련 문제