【问题标题】:sendto: Network unreachablesendto:网络不可达
【发布时间】:2010-12-12 22:35:07
【问题描述】:

我有两台机器正在测试我的代码,一台工作正常,另一台我遇到了一些问题,我不知道为什么会这样。

我正在为我的项目的网络部分使用一个对象 (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()。谁能帮我?我真的很感激。

解决方案

事实证明,服务器不喜欢我设置初始 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;

谁能解释一下?

【问题讨论】:

  • 我假设您已经确认不只是您的程序出现此错误?您是否检查过是否可以 ping google.com 或您尝试发送到的机器。听起来更像是服务器问题而不是代码问题
  • 好吧,我 ssh 到有问题的机器上,所以我不认为是这样。

标签: c++ sockets


【解决方案1】:

需要检查的几件事 1. 运行服务器。使用 netstat 并查看服务器绑定的 IP 和端口。 IP 是 localhost IP 还是 0.0.0.0 IP? 2. 一旦您知道服务器正在侦听正确的端口并且地址正常,请检查您是否可以 telnet 到该端口。试试这个 telnet 3.这将尝试连接到端口(不是telnet服务器没关系,你可以用它来检查连接) 4. 如果 telnet 能够连接到端口,即没有错误,您可以检查客户端代码以查看您缺少什么。 就像 Glen 提到的那样,您是否检查过您是否能够从客户端计算机进行远程连接?

【讨论】:

    【解决方案2】:

    您似乎通过选择第一个可以创建套接字和绑定到的接口来选择服务器侦听的接口?这似乎是一种新颖的方法......

    当然,在具有多个 NIC 的机器上,您很可能希望绑定到一个而不是另一个,并且您很可能知道您想要哪个;例如,如果我们有 2 个 NIC,一个面向 Internet,一个面向内部专用网络,您可能知道要绑定到哪个接口并在其上提供服务,您的代码似乎在做的只是选择第一个既可以创建套接字也可以绑定到...

    无论如何,我想在您无法从您发送的机器上绑定到一个接口,该接口指向一个与您的目标地址没有连接的网络...既然您说您可以接收数据在那个套接字上,从代码 sn-p 我假设你正试图发回你刚从它收到的地址,看起来像你遇到问题时正在运行的机器的路由表错误,它不能从自己路由到目标机器,但目标机器可以路由到服务器......

    【讨论】:

      猜你喜欢
      • 2012-04-28
      • 2017-11-30
      • 1970-01-01
      • 1970-01-01
      • 2011-10-13
      • 1970-01-01
      • 1970-01-01
      • 2019-11-15
      • 2013-10-24
      相关资源
      最近更新 更多