2010-05-06 4 views
1

У меня есть две машины, на которых я тестирую свой код, один работает отлично, другой у меня проблемы, и я не знаю, почему это так.sendto: Network unreachable

Я использую объект (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() моего сервера. В котором я получаю сообщение «Ошибка: сеть недоступна». Я сначала вызываю gercv() перед вызовом gsend(). Может кто-нибудь мне помочь? Я был бы очень признателен.

РЕШЕНИЕ

Оказывается, что сервер не нравится, как я создал первоначальную структуру 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

+0

Ну, я ssh на машине, у которой есть проблема, поэтому я не думаю, что это так. – devin

ответ

0

Немного вещей для проверки 1. Запустите сервер. Используйте netstat и посмотрите IP-адрес и порт, к которому привязан сервер. Является ли IP локальным IP-адресом или IP-адресом 0.0.0.0? 2. Как только вы узнаете, что сервер прослушивает правый порт и что адрес в порядке, проверьте, можете ли вы использовать telnet для порта. Просто попробуйте этот telnet 3. Это попытается подключиться к порту (неважно, что это не сервер telnet, вы можете использовать это для проверки возможности подключения). 4. Если telnet может подключиться к порту, то нет ошибки, вы можете проверить код клиента, чтобы узнать, чего не хватает. И, как сказал Глен, вы проверили, что вы можете делать удаленные подключения с клиентской машины?

0

Кажется, что вы выбираете интерфейс, который слушает ваш сервер, выбирая первый интерфейс, с которым вы можете создать сокет и связать его? Это кажется новым способом сделать это ...

Наверняка, на машине с несколькими сетевыми адаптерами вы, скорее всего, захотите привязываться к одному, а не к другому, и вы, скорее всего, знаете, какой из них вы хотите; например, если у нас есть 2 сетевых адаптера, один из которых обращен к Интернету, а другой - во внутреннюю частную сеть, вы, вероятно, знаете, с каким интерфейсом вы хотите привязываться и предоставлять свою услугу, и что делает ваш код - просто выберите первый, могут создавать сокет и связывать его с ...

Во всяком случае, я бы предположил, что на машине, которую вы не можете отправлять, вы привязываетесь к интерфейсу, который указывает на сеть, у которой нет возможности подключения к ваш целевой адрес ... Поскольку вы говорите, что можете получать данные в этом сокете и из фрагмента кода, я предполагаю, что вы пытаетесь отправить обратно на тот адрес, который вы только что получили от него, выглядит как таблица маршрутизации машины, повторное выполнение, когда у вас возникли проблемы, некорректно настроено и что он не может маршрутизировать из себя на целевую машину, но целевой компьютер МОЖЕТ направить на сервер ...