2010-05-06 89 views
1

我有兩臺機器我正在測試我的代碼,其中一個正常工作,另一個我遇到一些問題,我不知道它爲什麼。sendto:網絡不可達

我正在使用對象(C++)作爲我的項目的網絡部分。在服務器端,我這樣做:(爲清晰起見刪除錯誤檢查)

 res = getaddrinfo(NULL, port, &hints, &server)) < 0 

    for(p=server; p!=NULL; p=p->ai_next){ 
      fd = socket(p->ai_family, p->ai_socktype, p->ai_protocol); 
      if(fd<0){ 
        continue; 
        } 

      if(bind(fd, p->ai_addr, p->ai_addrlen)<0){ 
        close(fd); 
        continue; 
        } 
      break; 
      } 

這一切都有效。然後,我讓一個對象與此構造

net::net(int fd, struct sockaddr *other, socklen_t *other_len){ 
     int counter; 
     this->fd = fd; 
     if(other != NULL){ 
       this->other.sa_family = other->sa_family; 
       for(counter=0;counter<13;counter++) 
         this->other.sa_data[counter]=other->sa_data[counter]; 
       } 
     else 
       cerr << "Networking error" << endl; 
     this->other_len = *other_len; 
     } 

void net::gsend(string s){ 
     if(sendto(this->fd, s.c_str(), s.size()+1, 0, &(this->other), this->other_len)<0){ 
       cerr << "Error Sending, " << s << endl; 
       cerr << strerror(errno) << endl; 
       } 
     return; 
     } 

    string net::grecv(){ 
     stringstream ss; 
     string s; 
     char buf[BUFSIZE]; 
     buf[BUFSIZE-1] = '\0'; 

     if(recvfrom(this->fd, buf, BUFSIZE-1, 0, &(this->other), &(this->other_len))<0){ 
       cerr << "Error Recieving\n"; 
       cerr << strerror(errno) << endl; 
       } 

     // convert to c++ string and if there are multiple trailing ';' remove them 
     ss << buf; 
     s=ss.str(); 
     while(s.find(";;", s.size()-2) != string::npos) 
       s.erase(s.size()-1,1); 
     return s; 
     }  

所以我的問題是,是一臺機器上,一切工作正常。另一方面,一切正常,直到我打電話給我的服務器的gsend()函數。我在其中收到「錯誤:網絡無法訪問」。我在調用gsend()之前先調用gercv()。誰能幫我?我真的很感激。

SOLUTION

原來服務器不喜歡我設置初始sockaddr結構體的方式。我這樣做:

 struct addrinfo hints; 
    memset(&hints, 0, sizeof(struct addrinfo)); 
    hints.ai_family = AF_UNSPEC; 
    hints.ai_socktype = SOCK_DGRAM; 
    hints.ai_flags = AI_PASSIVE; 
    hints.ai_protocol = IPPROTO_UDP; 

當它應該是這樣的

 struct addrinfo hints; 
    memset(&hints, 0, sizeof(struct addrinfo)); 
    hints.ai_family = AF_UNSPEC; 
    hints.ai_socktype = SOCK_DGRAM; 

任何人都可以解釋一下嗎?

+0

我假設你已經驗證過,這不僅僅是你的程序有這個錯誤?你有沒有檢查你是否可以ping通google.com或試圖發送給你的機器。聽起來更像是一個服務器問題,而不是代碼問題 – Glen 2010-05-06 16:25:42

+0

好吧,我ssh到有問題的機器上,所以我不認爲就是這樣。 – devin 2010-05-06 19:43:11

回答

0

很少有事情要檢查 1.運行服務器。使用netstat並查看IP和服務器綁定的端口。 IP是本地主機IP還是0.0.0.0 IP? 2.一旦您知道服務器正在偵聽正確的端口並且地址正常,請檢查您是否可以telnet到端口。剛剛嘗試這一點的telnet 3.這將嘗試對端口的連接(不要緊,它是不是一個telnet服務器,你可以用它來檢查連接) 4.如果Telnet能夠連接到端口即無錯誤,然後您可以檢查客戶端代碼以查看缺少的內容。 就像Glen提到的那樣,你是否檢查過能夠從客戶端機器進行遠程連接?

0

看起來您正在選擇您的服務器偵聽的接口,方法是選擇您可以創建套接字並綁定到的第一個接口?這似乎是一種新穎的方式...

當然,在一臺有多個NIC的機器上,你很可能想要綁定一個而不是另一個,你很可能知道你想要哪一個;例如,如果我們有兩塊網卡,一塊麪向互聯網,另一塊麪向內部專用網絡,那麼您可能知道要綁定哪個接口並提供服務,而您的代碼似乎在做什麼只是選擇第一個接口既可以創建一個套接字並綁定到...

無論如何,我會想象在機器上,你不能從你發送要綁定到在一個網絡,沒有連接到指點的接口你的目標地址......既然你說你可以在那個套接字和代碼片段上接收數據,我假設你試圖發回你剛剛收到的地址,它看起來像是機器的路由表,當你遇到問題時重新開始運行不正確,並且它不能從自己路由到目標機器,但目標機器可以路由到服務器...