2013-01-21 31 views
1

我試圖使用功能getaddrinfo與被動套接字/偵聽器,而不是直接填充舊的sockaddr結構。 我的目的是打開一個套接字並將其綁定到一個端口。基本上我正在建立一個服務器。getaddrinfo返回2結果與本地主機

我不知道爲什麼,但getaddrinfo返回2個結果;因爲在第二次下面的循環中,我調用了bind,它會退出,並顯示「地址已被使用」的錯誤。 你知道如何解決這個問題,如果它是正確的,它在一個循環?

  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

嗨Linuxios。你是對的,它的工作原理。事情是這樣的(我現在才意識到)。我必須打電話也聽(並最終接受)。一旦我打電話聽,那麼地址就會被使用,並且我得到了那個錯誤。在這種情況下,我必須放棄2個結果中的哪一個(如果我必須?)。 –

+2

@AbruzzoForteeGentile:您應該使用第一個成功創建套接字的套接字。 – Linuxios

+0

好的。我會這樣做盡管它是IPV4或IPV6(我會回頭瞭解它們之間的區別)。非常感謝! –

0

這是在redhat的機器或許?有一個衆所周知的錯誤,因爲/etc/hosts/列出localhost兩次,當你請求具體AF_INET你實際上得到相同的結果兩次;一次用於IPv4,一次用於IPv6翻譯。

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

+0

嗨LeoNerd。我正在Ubuntu上試用這段代碼。 –