sendto: сеть недоступна - PullRequest
2 голосов
/ 06 мая 2010

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

Я использую объект (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;

Может кто-нибудь объяснить это?

Ответы [ 2 ]

0 голосов
/ 06 мая 2010

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

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

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

0 голосов
/ 06 мая 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...