首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >sendto:网络不可达

sendto:网络不可达
EN

Stack Overflow用户
提问于 2010-05-06 23:26:49
回答 2查看 6.3K关注 0票数 2

我有两台机器在测试我的代码,一台运行良好,另一台我有一些问题,我不知道为什么。

我为我的项目的网络部分使用了一个对象(C++)。在服务器端,我这样做:(为了清晰起见,删除了错误检查)

代码语言:javascript
复制
     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;
             }

这一切都行得通。然后我用这个构造函数创建了一个对象

代码语言:javascript
复制
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结构的方式。我是这样做的:

代码语言:javascript
复制
     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;

它本应该是这样的

代码语言:javascript
复制
     struct addrinfo hints;
     memset(&hints, 0, sizeof(struct addrinfo));
     hints.ai_family = AF_UNSPEC;
     hints.ai_socktype = SOCK_DGRAM;

有人能解释这个吗?

EN

回答 2

Stack Overflow用户

发布于 2010-05-07 00:53:50

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

票数 0
EN

Stack Overflow用户

发布于 2010-05-07 01:11:17

您似乎是在选择服务器侦听的接口,您选择的第一个接口既可以为其创建套接字,也可以绑定到该接口。这似乎是一种新颖的方法……

当然,在具有多个NIC的机器上,您很可能希望绑定到一个而不是另一个,并且您可能知道您想要绑定哪一个;例如,如果我们有两个NIC,一个面向internet,另一个面向内部私有网络,您可能知道要绑定到哪个接口并在其上提供服务,您的代码看起来只是选择了第一个,它既可以为其创建套接字,也可以绑定到它……

无论如何,我可以想象一下,在你不能发送的机器上,你绑定了一个指向一个网络的接口,而这个网络并没有连接到你的目标地址……既然您说您可以在套接字上接收数据,并从代码片段中接收数据,那么我假设您正在尝试发送回您刚刚从它接收到地址,当您遇到问题时,您正在运行的机器的路由表看起来像是错误地设置,它不能从自身路由到目标机器,但目标机器可以路由到服务器……

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2782259

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档