sendto:网络无法访问

时间:2010-05-06 15:26:49

标签: c++ sockets

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

我正在使用一个对象(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;

任何人都能解释一下吗?

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

通过选择第一个可以为其创建套接字并绑定到的接口,您似乎正在选择服务器侦听的接口?这似乎是一种新颖的方式......

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

无论如何,我想在您无法发送的机器上绑定到指向无法连接到目标地址的网络的接口...因为您说您可以接收数据在该套接字上,从代码片段开始,我假设您尝试发送回刚收到的地址,看起来当您遇到问题时正在运行的机器的路由表设置不正确,它无法从自身路由到目标机器,但目标机器CAN路由到服务器......