出现 Errno 代码 113(没有到主机的路由器)时如何排除故障?
我有一台Linux嵌入式设备,wifi模块处于并发模式。目前遇到一个问题,就是嵌入式设备在连接A设备时,通过“arp”命令获取A设备的IP,设置addrinfo结构(非阻塞),通过这个addrinfo进行Connect()函数,完成TCP握手。此时有几率会不断出现Errno code 113(no router to host)而导致连接失败。设备A和嵌入式设备确认没有防火墙设置。这个问题是间歇性的,错误出现5分钟以上后又恢复,过一段时间又出现。
附上相关代码
struct addrinfo hints, *servinfo, *p;
int rv;
char ipstr[INET6_ADDRSTRLEN];
bool SucessFlag = true;
static int failedtoconcnt[10];
static int StartRTC[10];
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;//ipv4 & ipv6
hints.ai_socktype = SOCK_STREAM;//tcp
cout << "Try to Connect IP: " << chIP << "Port "<< chPort << endl;
if (strlen(chIP) < 6) return 2;
for(int j=0;j<2;j++){
if ((rv = getaddrinfo(chIP, chPort, &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
return -1;
}
void *addr;
if (servinfo->ai_family == AF_INET) { // IPv4
struct sockaddr_in *ipv4 = (struct sockaddr_in *)servinfo->ai_addr;
addr = &(ipv4->sin_addr);
inet_ntop(servinfo->ai_family, addr, ipstr, sizeof(ipstr));
} else { // IPv6
struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)servinfo->ai_addr;
addr = &(ipv6->sin6_addr);
inet_ntop(servinfo->ai_family, addr, ipstr, sizeof ipstr);
}
for (p = servinfo; p != NULL; p = p->ai_next) {
if ((sockfd[id] = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
perror("client: socket Error");
continue;
}
if (sockfd[id] != 0){
for(int i=0;i<MaxID;i++){
if (ModTcpIPA->InvConnectID[i] == 1){
if (sockfd[id] == sockfd[i+1] && id != i+1){
DC_DEBUG_NL("sockfd[%d]=%d", id, sockfd[id]);
DC_DEBUG_NL("sockfd[%d]=%d", i+1, sockfd[i+1]);
CloseAllSock();
SucessFlag = false;
}
}
}
}
fcntl(sockfd[id], F_SETFL, O_NONBLOCK);
if (connect(sockfd[id], p->ai_addr, p->ai_addrlen) == 0) break;
sleep(1);
printf("1errno: %2d\t%s\n",errno,strerror(errno));
if (connect(sockfd[id], p->ai_addr, p->ai_addrlen) == 0) break;
sleep(1);
printf("2errno: %2d\t%s\n",errno,strerror(errno));
if (connect(sockfd[id], p->ai_addr, p->ai_addrlen) == 0) break;
sleep(1);
printf("3errno: %2d\t%s\n",errno,strerror(errno));
if (connect(sockfd[id], p->ai_addr, p->ai_addrlen) == 0) break;
sleep(1);
printf("4errno: %2d\t%s\n",errno,strerror(errno));
}
if (p == NULL) {
DC_DEBUG_NL("client: failed to connect");
fprintf(stderr, "client: failed to connect\n");
close(sockfd[id]);
return 1;
}
inet_ntop(p->ai_family, toget_in_addr((struct sockaddr *)p->ai_addr), ipstr, sizeof ipstr);
freeaddrinfo(servinfo);
if (SucessFlag == true){
break;
}
}
return 0;
答案1
输入以下内容你会看到什么:
$ route
在您想要运行该软件的机器上的控制台中?
您应该看到类似以下内容的内容:
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
default 1.2.3.4 0.0.0.0 UG 0 0 0 eth0
目的地default
(0.0.0.0) 是使路由工作的关键。有点像魔术。如果没有其他 IP 匹配,则使用默认 IP 发送数据,然后网关负责进一步转发或处理数据包。
如果你的路线都UG
没有标志列,那么您完全没有输入网关。如果有这样一行,那么可能是网关 IP 出了问题。
如果您有名称解析问题,请尝试-n
命令行选项:
$ route -n
如果这不是问题所在,我会通过打印出代码来确保我获取了正确的 IP 地址。这样你就能知道代码中是否有错误。我看不出有什么问题,尽管你的代码很难读(它是老旧的 C 而不是 C++...你的类在哪里?我有一个项目要做这样的事情这里它使用另一个项目处理 IP 地址,因为太乱了!)